From: Joe Orton Date: Tue, 8 Sep 2020 14:08:22 +0000 (+0000) Subject: Further re-unification of code duplicated across mod_cgi/mod_cgid into X-Git-Tag: 2.5.0-alpha2-ci-test-only~1210 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eabfcda175c138ffaa461ead97f361a67cbe6c6f;p=thirdparty%2Fapache%2Fhttpd.git Further re-unification of code duplicated across mod_cgi/mod_cgid into cgi_common.h. Functional changes: - brings the PR 61980 fix to mod_cgid as well, and - some mod_cgid-specific APLOGNOs are dropped in favour of the code used in the equivalent error path in mod_cgi ... otherwise no user-visible changes (intended). * modules/generators/cgi_common.h (log_scripterror, log_script_err): Move here from mod_cgi. (cgi_handle_exec): Move here, renamed from mod_cgi's handle_exec. (cgi_optfns_retrieve): New function, split out from mod_cgi's cgi_post_config. * modules/generators/mod_cgid.c: Adjust accordingly, update to pass logno separately. (register_hooks): Register cgi_optfns_retrieve. * modules/generators/mod_cgi.c: Adjust accordingly. (register_hooks): Register cgi_optfns_retrieve. Github: closes #141 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1881559 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/.travis.yml b/.travis.yml index 09d89b4cf09..16febaaf05f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -97,8 +97,8 @@ jobs: env: CONFIG="--enable-mods-shared=reallyall" TEST_ARGS="-order=random" # ------------------------------------------------------------------------- - - name: Linux Ubuntu, Prefork MPM, all-modules - env: CONFIG="--enable-mods-shared=reallyall --with-mpm=prefork" + - name: Linux Ubuntu, Prefork MPM, all-modules (except cgid) + env: CONFIG="--enable-mods-shared=reallyall --with-mpm=prefork --disable-cgid" # ------------------------------------------------------------------------- - name: Linux Ubuntu, Worker MPM, all-modules env: CONFIG="--enable-mods-shared=reallyall --with-mpm=worker" diff --git a/modules/generators/cgi_common.h b/modules/generators/cgi_common.h index dc2bba962bb..69df73ce68f 100644 --- a/modules/generators/cgi_common.h +++ b/modules/generators/cgi_common.h @@ -27,6 +27,18 @@ #include "httpd.h" #include "util_filter.h" +static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgi_pfn_gtv; +static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgi_pfn_ps; + +/* These functions provided by mod_cgi.c/mod_cgid.c still. */ +static int log_script(request_rec *r, cgi_server_conf * conf, int ret, + char *dbuf, const char *sbuf, apr_bucket_brigade *bb, + apr_file_t *script_err); +static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb, char *s); +static apr_status_t include_cmd(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb, const char *command); + /* Read and discard all output from the brigade. Note that with the * CGI bucket, the brigade will become empty once the script's stdout * is closed (or on error/timeout), but the stderr output may not have @@ -48,6 +60,166 @@ static void discard_script_output(apr_bucket_brigade *bb) } } +static int log_scripterror(request_rec *r, cgi_server_conf *conf, int ret, + apr_status_t rv, const char *logno, + const char *error) +{ + apr_file_t *f = NULL; + apr_finfo_t finfo; + char time_str[APR_CTIME_LEN]; + + /* Intentional no APLOGNO */ + /* Callee provides APLOGNO in error text */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "%sstderr from %s: %s", logno ? logno : "", r->filename, error); + + /* XXX Very expensive mainline case! Open, then getfileinfo! */ + if (!conf->logname || + ((apr_stat(&finfo, conf->logname, + APR_FINFO_SIZE, r->pool) == APR_SUCCESS) && + (finfo.size > conf->logbytes)) || + (apr_file_open(&f, conf->logname, + APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, + r->pool) != APR_SUCCESS)) { + return ret; + } + + /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */ + apr_ctime(time_str, apr_time_now()); + apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, + r->args ? "?" : "", r->args ? r->args : "", r->protocol); + /* "%% 500 /usr/local/apache/cgi-bin */ + apr_file_printf(f, "%%%% %d %s\n", ret, r->filename); + + apr_file_printf(f, "%%error\n%s\n", error); + + apr_file_close(f); + return ret; +} + +/* Soak up stderr from a script and redirect it to the error log. + */ +static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err) +{ + char argsbuffer[HUGE_STRING_LEN]; + char *newline; + apr_status_t rv; + cgi_server_conf *conf = ap_get_module_config(r->server->module_config, &cgi_module); + + while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN, + script_err)) == APR_SUCCESS) { + + newline = strchr(argsbuffer, '\n'); + if (newline) { + char *prev = newline - 1; + if (prev >= argsbuffer && *prev == '\r') { + newline = prev; + } + + *newline = '\0'; + } + log_scripterror(r, conf, r->status, 0, APLOGNO(01215), argsbuffer); + } + + return rv; +} + +static apr_status_t cgi_handle_exec(include_ctx_t *ctx, ap_filter_t *f, + apr_bucket_brigade *bb) +{ + char *tag = NULL; + char *tag_val = NULL; + request_rec *r = f->r; + char *file = r->filename; + char parsed_string[MAX_STRING_LEN]; + + if (!ctx->argc) { + ap_log_rerror(APLOG_MARK, + (ctx->flags & SSI_FLAG_PRINTING) + ? APLOG_ERR : APLOG_WARNING, + 0, r, APLOGNO(03195) + "missing argument for exec element in %s", r->filename); + } + + if (!(ctx->flags & SSI_FLAG_PRINTING)) { + return APR_SUCCESS; + } + + if (!ctx->argc) { + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + if (ctx->flags & SSI_FLAG_NO_EXEC) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01228) "exec used but not allowed " + "in %s", r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + return APR_SUCCESS; + } + + while (1) { + cgi_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED); + if (!tag || !tag_val) { + break; + } + + if (!strcmp(tag, "cmd")) { + apr_status_t rv; + + cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), + SSI_EXPAND_LEAVE_NAME); + + rv = include_cmd(ctx, f, bb, parsed_string); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01229) "execution failure " + "for parameter \"%s\" to tag exec in file %s", + tag, r->filename); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + else if (!strcmp(tag, "cgi")) { + apr_status_t rv; + + cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), + SSI_EXPAND_DROP_NAME); + + rv = include_cgi(ctx, f, bb, parsed_string); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01230) "invalid CGI ref " + "\"%s\" in %s", tag_val, file); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01231) "unknown parameter " + "\"%s\" to tag exec in %s", tag, file); + SSI_CREATE_ERROR_BUCKET(ctx, f, bb); + break; + } + } + + return APR_SUCCESS; +} + +/* Hook to register exec= handling with mod_include. */ +static void cgi_optfns_retrieve(void) +{ + APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgi_pfn_reg_with_ssi; + + cgi_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler); + cgi_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value); + cgi_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string); + + if (cgi_pfn_reg_with_ssi && cgi_pfn_gtv && cgi_pfn_ps) { + /* Required by mod_include filter. This is how mod_cgi registers + * with mod_include to provide processing of the exec directive. + */ + cgi_pfn_reg_with_ssi("exec", cgi_handle_exec); + } +} + #ifdef WANT_CGI_BUCKET /* A CGI bucket type is needed to catch any output to stderr from the * script; see PR 22030. */ diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c index d8fc7b7a55e..421124a0cb1 100644 --- a/modules/generators/mod_cgi.c +++ b/modules/generators/mod_cgi.c @@ -61,9 +61,6 @@ module AP_MODULE_DECLARE_DATA cgi_module; -static APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgi_pfn_reg_with_ssi; -static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgi_pfn_gtv; -static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgi_pfn_ps; static APR_OPTIONAL_FN_TYPE(ap_cgi_build_command) *cgi_build_command; /* Read and discard the data in the brigade produced by a CGI script */ @@ -96,6 +93,11 @@ typedef struct { apr_interval_time_t timeout; } cgi_dirconf; +#if APR_FILES_AS_SOCKETS +#define WANT_CGI_BUCKET +#endif +#include "cgi_common.h" + static void *create_cgi_config(apr_pool_t *p, server_rec *s) { cgi_server_conf *c = @@ -185,69 +187,6 @@ AP_INIT_TAKE1("CGIScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_C {NULL} }; -static int log_scripterror(request_rec *r, cgi_server_conf * conf, int ret, - apr_status_t rv, char *logno, char *error) -{ - apr_file_t *f = NULL; - apr_finfo_t finfo; - char time_str[APR_CTIME_LEN]; - - /* Intentional no APLOGNO */ - /* Callee provides APLOGNO in error text */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "%sstderr from %s: %s", logno ? logno : "", r->filename, error); - - /* XXX Very expensive mainline case! Open, then getfileinfo! */ - if (!conf->logname || - ((apr_stat(&finfo, conf->logname, - APR_FINFO_SIZE, r->pool) == APR_SUCCESS) && - (finfo.size > conf->logbytes)) || - (apr_file_open(&f, conf->logname, - APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, - r->pool) != APR_SUCCESS)) { - return ret; - } - - /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */ - apr_ctime(time_str, apr_time_now()); - apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, - r->args ? "?" : "", r->args ? r->args : "", r->protocol); - /* "%% 500 /usr/local/apache/cgi-bin */ - apr_file_printf(f, "%%%% %d %s\n", ret, r->filename); - - apr_file_printf(f, "%%error\n%s\n", error); - - apr_file_close(f); - return ret; -} - -/* Soak up stderr from a script and redirect it to the error log. - */ -static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err) -{ - char argsbuffer[HUGE_STRING_LEN]; - char *newline; - apr_status_t rv; - cgi_server_conf *conf = ap_get_module_config(r->server->module_config, &cgi_module); - - while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN, - script_err)) == APR_SUCCESS) { - - newline = strchr(argsbuffer, '\n'); - if (newline) { - char *prev = newline - 1; - if (prev >= argsbuffer && *prev == '\r') { - newline = prev; - } - - *newline = '\0'; - } - log_scripterror(r, conf, r->status, 0, APLOGNO(01215), argsbuffer); - } - - return rv; -} - static int log_script(request_rec *r, cgi_server_conf * conf, int ret, char *dbuf, const char *sbuf, apr_bucket_brigade *bb, apr_file_t *script_err) @@ -568,11 +507,6 @@ static apr_status_t default_build_command(const char **cmd, const char ***argv, return APR_SUCCESS; } -#if APR_FILES_AS_SOCKETS -#define WANT_CGI_BUCKET -#endif -#include "cgi_common.h" - static int cgi_handler(request_rec *r) { int nph; @@ -814,107 +748,9 @@ static apr_status_t include_cmd(include_ctx_t *ctx, ap_filter_t *f, return APR_SUCCESS; } -static apr_status_t handle_exec(include_ctx_t *ctx, ap_filter_t *f, - apr_bucket_brigade *bb) -{ - char *tag = NULL; - char *tag_val = NULL; - request_rec *r = f->r; - char *file = r->filename; - char parsed_string[MAX_STRING_LEN]; - - if (!ctx->argc) { - ap_log_rerror(APLOG_MARK, - (ctx->flags & SSI_FLAG_PRINTING) - ? APLOG_ERR : APLOG_WARNING, - 0, r, APLOGNO(03195) - "missing argument for exec element in %s", r->filename); - } - - if (!(ctx->flags & SSI_FLAG_PRINTING)) { - return APR_SUCCESS; - } - - if (!ctx->argc) { - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - return APR_SUCCESS; - } - - if (ctx->flags & SSI_FLAG_NO_EXEC) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01228) "exec used but not allowed " - "in %s", r->filename); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - return APR_SUCCESS; - } - - while (1) { - cgi_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED); - if (!tag || !tag_val) { - break; - } - - if (!strcmp(tag, "cmd")) { - apr_status_t rv; - - cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), - SSI_EXPAND_LEAVE_NAME); - - rv = include_cmd(ctx, f, bb, parsed_string); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01229) "execution failure " - "for parameter \"%s\" to tag exec in file %s", - tag, r->filename); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - else if (!strcmp(tag, "cgi")) { - apr_status_t rv; - - cgi_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), - SSI_EXPAND_DROP_NAME); - - rv = include_cgi(ctx, f, bb, parsed_string); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01230) "invalid CGI ref " - "\"%s\" in %s", tag_val, file); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - else { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01231) "unknown parameter " - "\"%s\" to tag exec in %s", tag, file); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - - return APR_SUCCESS; -} - - -/*============================================================================ - *============================================================================ - * This is the end of the cgi filter code moved from mod_include. - *============================================================================ - *============================================================================*/ - - static int cgi_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { - cgi_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler); - cgi_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value); - cgi_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string); - - if ((cgi_pfn_reg_with_ssi) && (cgi_pfn_gtv) && (cgi_pfn_ps)) { - /* Required by mod_include filter. This is how mod_cgi registers - * with mod_include to provide processing of the exec directive. - */ - cgi_pfn_reg_with_ssi("exec", handle_exec); - } - /* This is the means by which unusual (non-unix) os's may find alternate * means to run a given command (e.g. shebang/registry parsing on Win32) */ @@ -930,6 +766,7 @@ static void register_hooks(apr_pool_t *p) static const char * const aszPre[] = { "mod_include.c", NULL }; ap_hook_handler(cgi_handler, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(cgi_post_config, aszPre, NULL, APR_HOOK_REALLY_FIRST); + ap_hook_optional_fn_retrieve(cgi_optfns_retrieve, NULL, NULL, APR_HOOK_MIDDLE); } AP_DECLARE_MODULE(cgi) = diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index 38038110550..b821b69b9af 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -80,11 +80,6 @@ module AP_MODULE_DECLARE_DATA cgid_module; static int cgid_start(apr_pool_t *p, server_rec *main_server, apr_proc_t *procnew); static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server); -static int handle_exec(include_ctx_t *ctx, ap_filter_t *f, apr_bucket_brigade *bb); - -static APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *cgid_pfn_reg_with_ssi; -static APR_OPTIONAL_FN_TYPE(ap_ssi_get_tag_and_value) *cgid_pfn_gtv; -static APR_OPTIONAL_FN_TYPE(ap_ssi_parse_string) *cgid_pfn_ps; static apr_pool_t *pcgi = NULL; static pid_t daemon_pid; @@ -220,6 +215,15 @@ typedef struct { #endif } cgid_req_t; +#define cgi_server_conf cgid_server_conf +#define cgi_module cgid_module + +#ifdef HAVE_CGID_FDPASSING +/* Pull in CGI bucket implementation. */ +#define WANT_CGI_BUCKET +#endif +#include "cgi_common.h" + /* This routine is called to create the argument list to be passed * to the CGI script. When suexec is enabled, the suexec path, user, and * group are the first three arguments to be passed; if not, all three @@ -573,7 +577,7 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, } static apr_status_t send_req(int fd, apr_file_t *errpipe, request_rec *r, - char *argv0, char **env, int req_type) + const char *argv0, char **env, int req_type) { int i; cgid_req_t req = {0}; @@ -1072,16 +1076,6 @@ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, if (ret != OK ) { return ret; } - cgid_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler); - cgid_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value); - cgid_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string); - - if ((cgid_pfn_reg_with_ssi) && (cgid_pfn_gtv) && (cgid_pfn_ps)) { - /* Required by mod_include filter. This is how mod_cgid registers - * with mod_include to provide processing of the exec directive. - */ - cgid_pfn_reg_with_ssi("exec", handle_exec); - } } return ret; } @@ -1192,68 +1186,6 @@ static const command_rec cgid_cmds[] = {NULL} }; -static int log_scripterror(request_rec *r, cgid_server_conf * conf, int ret, - apr_status_t rv, char *error) -{ - apr_file_t *f = NULL; - struct stat finfo; - char time_str[APR_CTIME_LEN]; - int log_flags = rv ? APLOG_ERR : APLOG_ERR; - - /* Intentional no APLOGNO */ - /* Callee provides APLOGNO in error text */ - ap_log_rerror(APLOG_MARK, log_flags, rv, r, - "%s: %s", error, r->filename); - - /* XXX Very expensive mainline case! Open, then getfileinfo! */ - if (!conf->logname || - ((stat(conf->logname, &finfo) == 0) - && (finfo.st_size > conf->logbytes)) || - (apr_file_open(&f, conf->logname, - APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, r->pool) != APR_SUCCESS)) { - return ret; - } - - /* "%% [Wed Jun 19 10:53:21 1996] GET /cgid-bin/printenv HTTP/1.0" */ - apr_ctime(time_str, apr_time_now()); - apr_file_printf(f, "%%%% [%s] %s %s%s%s %s\n", time_str, r->method, r->uri, - r->args ? "?" : "", r->args ? r->args : "", r->protocol); - /* "%% 500 /usr/local/apache/cgid-bin */ - apr_file_printf(f, "%%%% %d %s\n", ret, r->filename); - - apr_file_printf(f, "%%error\n%s\n", error); - - apr_file_close(f); - return ret; -} - -/* Soak up stderr from a script and redirect it to the error log. - * TODO: log_scripterror() and this could move to cgi_common.h. */ -static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err) -{ - char argsbuffer[HUGE_STRING_LEN]; - char *newline; - apr_status_t rv; - cgid_server_conf *conf = ap_get_module_config(r->server->module_config, &cgid_module); - - while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN, - script_err)) == APR_SUCCESS) { - - newline = strchr(argsbuffer, '\n'); - if (newline) { - char *prev = newline - 1; - if (prev >= argsbuffer && *prev == '\r') { - newline = prev; - } - - *newline = '\0'; - } - log_scripterror(r, conf, r->status, 0, argsbuffer); - } - - return rv; -} - static int log_script(request_rec *r, cgid_server_conf * conf, int ret, char *dbuf, const char *sbuf, apr_bucket_brigade *bb, apr_file_t *script_err) @@ -1359,13 +1291,6 @@ static int log_script(request_rec *r, cgid_server_conf * conf, int ret, return ret; } -/* Pull in CGI bucket implementation. */ -#define cgi_server_conf cgid_server_conf -#ifdef HAVE_CGID_FDPASSING -#define WANT_CGI_BUCKET -#endif -#include "cgi_common.h" - static int connect_to_daemon(int *sdptr, request_rec *r, cgid_server_conf *conf) { @@ -1381,7 +1306,7 @@ static int connect_to_daemon(int *sdptr, request_rec *r, ++connect_tries; if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { return log_scripterror(r, conf, HTTP_INTERNAL_SERVER_ERROR, errno, - APLOGNO(01255) "unable to create socket to cgi daemon"); + APLOGNO(01255), "unable to create socket to cgi daemon"); } if (connect(sd, (struct sockaddr *)server_addr, server_addr_len) < 0) { /* Save errno for later */ @@ -1402,7 +1327,7 @@ static int connect_to_daemon(int *sdptr, request_rec *r, } else { close(sd); - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, APLOGNO(01257) + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, APLOGNO(01257), "unable to connect to cgi daemon after multiple tries"); } } @@ -1418,13 +1343,15 @@ static int connect_to_daemon(int *sdptr, request_rec *r, if (connect_errno == ENOENT && apr_time_sec(apr_time_now() - ap_scoreboard_image->global->restart_time) > DEFAULT_CONNECT_STARTUP_DELAY) { - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, - apr_pstrcat(r->pool, APLOGNO(02833) "ScriptSock ", sockname, " does not exist", NULL)); + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, + APLOGNO(02833), + apr_pstrcat(r->pool, + "ScriptSock ", sockname, " does not exist", NULL)); } /* gotta try again, but make sure the cgid daemon is still around */ if (connect_errno != ENOENT && kill(daemon_pid, 0) != 0) { - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, APLOGNO(01258) + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, APLOGNO(01258), "cgid daemon is gone; is Apache terminating?"); } } @@ -1576,12 +1503,12 @@ static int cgid_handler(request_rec *r) argv0 = r->filename; if (!(ap_allow_options(r) & OPT_EXECCGI) && !is_scriptaliased(r)) { - return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01262) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01262), "Options ExecCGI is off in this directory"); } if (nph && is_included) { - return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01263) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01263), "attempt to include NPH CGI script"); } @@ -1590,12 +1517,12 @@ static int cgid_handler(request_rec *r) #error at mod_cgi.c for required code in this path. #else if (r->finfo.filetype == APR_NOFILE) { - return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01264) + return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01264), "script not found or unable to stat"); } #endif if (r->finfo.filetype == APR_DIR) { - return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01265) + return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(01265), "attempt to invoke directory as script"); } @@ -1603,7 +1530,7 @@ static int cgid_handler(request_rec *r) r->path_info && *r->path_info) { /* default to accept */ - return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01266) + return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(01266), "AcceptPathInfo off disallows user's path"); } /* @@ -1617,7 +1544,7 @@ static int cgid_handler(request_rec *r) #ifdef HAVE_CGID_FDPASSING rv = apr_file_pipe_create(&script_err, &errpipe_out, r->pool); if (rv) { - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10176) + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10176), "could not create pipe for stderr"); } #else @@ -1639,7 +1566,7 @@ static int cgid_handler(request_rec *r) rv = send_req(sd, errpipe_out, r, argv0, env, CGI_REQ); if (rv != APR_SUCCESS) { - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10245) + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10245), "could not send request to cgi daemon"); } @@ -1657,7 +1584,7 @@ static int cgid_handler(request_rec *r) cleanup_script, apr_pool_cleanup_null); } else { - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10246) + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10246), "failed reading PID from cgi daemon"); } @@ -1710,15 +1637,7 @@ static int cgid_handler(request_rec *r) return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err); } - - - -/*============================================================================ - *============================================================================ - * This is the beginning of the cgi filter code moved from mod_include. This - * is the code required to handle the "exec" SSI directive. - *============================================================================ - *============================================================================*/ +/* Handling include= for mod_include. */ static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f, apr_bucket_brigade *bb, char *s) { @@ -1803,7 +1722,7 @@ static void add_ssi_vars(request_rec *r) } static int include_cmd(include_ctx_t *ctx, ap_filter_t *f, - apr_bucket_brigade *bb, char *command) + apr_bucket_brigade *bb, const char *command) { char **env; int sd; @@ -1869,91 +1788,6 @@ static int include_cmd(include_ctx_t *ctx, ap_filter_t *f, return APR_SUCCESS; } -static apr_status_t handle_exec(include_ctx_t *ctx, ap_filter_t *f, - apr_bucket_brigade *bb) -{ - char *tag = NULL; - char *tag_val = NULL; - request_rec *r = f->r; - char *file = r->filename; - char parsed_string[MAX_STRING_LEN]; - - if (!ctx->argc) { - ap_log_rerror(APLOG_MARK, - (ctx->flags & SSI_FLAG_PRINTING) - ? APLOG_ERR : APLOG_WARNING, - 0, r, APLOGNO(03196) - "missing argument for exec element in %s", r->filename); - } - - if (!(ctx->flags & SSI_FLAG_PRINTING)) { - return APR_SUCCESS; - } - - if (!ctx->argc) { - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - return APR_SUCCESS; - } - - if (ctx->flags & SSI_FLAG_NO_EXEC) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01271) "exec used but not allowed " - "in %s", r->filename); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - return APR_SUCCESS; - } - - while (1) { - cgid_pfn_gtv(ctx, &tag, &tag_val, SSI_VALUE_DECODED); - if (!tag || !tag_val) { - break; - } - - if (!strcmp(tag, "cmd")) { - apr_status_t rv; - - cgid_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), - SSI_EXPAND_LEAVE_NAME); - - rv = include_cmd(ctx, f, bb, parsed_string); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01272) - "execution failure for parameter \"%s\" " - "to tag exec in file %s", tag, r->filename); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - else if (!strcmp(tag, "cgi")) { - apr_status_t rv; - - cgid_pfn_ps(ctx, tag_val, parsed_string, sizeof(parsed_string), - SSI_EXPAND_DROP_NAME); - - rv = include_cgi(ctx, f, bb, parsed_string); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01273) "invalid CGI ref " - "\"%s\" in %s", tag_val, file); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - else { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01274) "unknown parameter " - "\"%s\" to tag exec in %s", tag, file); - SSI_CREATE_ERROR_BUCKET(ctx, f, bb); - break; - } - } - - return APR_SUCCESS; -} -/*============================================================================ - *============================================================================ - * This is the end of the cgi filter code moved from mod_include. - *============================================================================ - *============================================================================*/ - - static void register_hook(apr_pool_t *p) { static const char * const aszPre[] = { "mod_include.c", NULL }; @@ -1961,6 +1795,7 @@ static void register_hook(apr_pool_t *p) ap_hook_pre_config(cgid_pre_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(cgid_init, aszPre, NULL, APR_HOOK_MIDDLE); ap_hook_handler(cgid_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_optional_fn_retrieve(cgi_optfns_retrieve, NULL, NULL, APR_HOOK_MIDDLE); } AP_DECLARE_MODULE(cgid) = {