|
|
|
@ -703,6 +703,15 @@ static int cgi_write_request(server *srv, handler_ctx *hctx, int fd) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static struct stat * cgi_stat(server *srv, connection *con, buffer *path, struct stat *st) { |
|
|
|
|
/* CGI might be executable even if it is not readable
|
|
|
|
|
* (stat_cache_get_entry() currently checks file is readable)*/ |
|
|
|
|
stat_cache_entry *sce; |
|
|
|
|
return (HANDLER_ERROR != stat_cache_get_entry(srv, con, path, &sce)) |
|
|
|
|
? &sce->st |
|
|
|
|
: (0 == stat(path->ptr, st)) ? st : NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int cgi_create_env(server *srv, connection *con, plugin_data *p, handler_ctx *hctx, buffer *cgi_handler) { |
|
|
|
|
char *args[3]; |
|
|
|
|
int to_cgi_fds[2]; |
|
|
|
@ -713,7 +722,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, handler_ |
|
|
|
|
if (!buffer_string_is_empty(cgi_handler)) { |
|
|
|
|
/* stat the exec file */ |
|
|
|
|
struct stat st; |
|
|
|
|
if (-1 == (stat(cgi_handler->ptr, &st))) { |
|
|
|
|
if (NULL == cgi_stat(srv, con, cgi_handler, &st)) { |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbss", |
|
|
|
|
"stat for cgi-handler", cgi_handler, |
|
|
|
|
"failed:", strerror(errno)); |
|
|
|
@ -888,7 +897,6 @@ static int mod_cgi_patch_connection(server *srv, connection *con, plugin_data *p |
|
|
|
|
|
|
|
|
|
URIHANDLER_FUNC(cgi_is_handled) { |
|
|
|
|
plugin_data *p = p_d; |
|
|
|
|
stat_cache_entry *sce = NULL; |
|
|
|
|
struct stat stbuf; |
|
|
|
|
struct stat *st; |
|
|
|
|
data_string *ds; |
|
|
|
@ -901,14 +909,8 @@ URIHANDLER_FUNC(cgi_is_handled) { |
|
|
|
|
ds = (data_string *)array_match_key_suffix(p->conf.cgi, con->physical.path); |
|
|
|
|
if (NULL == ds) return HANDLER_GO_ON; |
|
|
|
|
|
|
|
|
|
if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) { |
|
|
|
|
st = &sce->st; |
|
|
|
|
} else { |
|
|
|
|
/* CGI might be executable even if it is not readable
|
|
|
|
|
* (stat_cache_get_entry() currently checks file is readable)*/ |
|
|
|
|
if (0 != stat(con->physical.path->ptr, &stbuf)) return HANDLER_GO_ON; |
|
|
|
|
st = &stbuf; |
|
|
|
|
} |
|
|
|
|
st = cgi_stat(srv, con, con->physical.path, &stbuf); |
|
|
|
|
if (NULL == st) return HANDLER_GO_ON; |
|
|
|
|
|
|
|
|
|
if (!S_ISREG(st->st_mode)) return HANDLER_GO_ON; |
|
|
|
|
if (p->conf.execute_x_only == 1 && (st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) return HANDLER_GO_ON; |
|
|
|
|