39#define APR_WANT_STRFUNC
42#if APR_HAVE_SYS_SOCKET_H
43#include <sys/socket.h>
48#if APR_HAVE_SYS_TYPES_H
63#include "../filters/mod_include.h"
72#if APR_HAVE_STRUCT_RLIMIT
73#if defined (RLIMIT_CPU) || defined (RLIMIT_NPROC) || defined (RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
74#define AP_CGID_USE_RLIMIT
78module AP_MODULE_DECLARE_DATA cgid_module;
105#define DAEMON_STARTUP_ERROR 254
133#define DEFAULT_LOGBYTES 10385760
134#define DEFAULT_BUFBYTES 1024
135#define DEFAULT_SOCKET "cgisock"
141#define ERRFN_USERDATA_KEY "CGIDCHILDERRFN"
150#ifndef DEFAULT_CGID_LISTENBACKLOG
151#define DEFAULT_CGID_LISTENBACKLOG 100
163#ifndef DEFAULT_CONNECT_ATTEMPTS
164#define DEFAULT_CONNECT_ATTEMPTS 15
167#ifndef DEFAULT_CONNECT_STARTUP_DELAY
168#define DEFAULT_CONNECT_STARTUP_DELAY 60
177#ifdef AP_CGID_USE_RLIMIT
183#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
212#ifdef AP_CGID_USE_RLIMIT
217#define cgi_server_conf cgid_server_conf
218#define cgi_module cgid_module
220#ifdef HAVE_CGID_FDPASSING
222#define WANT_CGI_BUCKET
249 if (
args[x] ==
'+') {
281#if APR_HAS_OTHER_CHILD
304 "cgid daemon failed to initialize");
308 "cgid daemon process died, restarting");
333 "Couldn't unlink unix domain socket %s",
355#ifndef HAVE_CGID_FDPASSING
389 msg.msg_control =
u.buf;
390 msg.msg_controllen =
sizeof(
u.buf);
460#ifndef HAVE_CGID_FDPASSING
466 struct msghdr msg = { 0 };
474 msg.msg_iovlen =
count;
477 msg.msg_control =
u.buf;
478 msg.msg_controllen =
sizeof(
u.buf);
570#ifdef AP_CGID_USE_RLIMIT
579 const char *
argv0,
char **
env,
int req_type)
641#if defined(RLIMIT_CPU) && defined(AP_CGID_USE_RLIMIT)
643 req.limits.limit_cpu = *(
core_conf->limit_cpu);
644 req.limits.limit_cpu_set = 1;
647 req.limits.limit_cpu_set = 0;
651#if defined(AP_CGID_USE_RLIMIT) && (defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS))
653 req.limits.limit_mem = *(
core_conf->limit_mem);
654 req.limits.limit_mem_set = 1;
657 req.limits.limit_mem_set = 0;
662#if defined(RLIMIT_NPROC) && defined(AP_CGID_USE_RLIMIT)
664 req.limits.limit_nproc = *(
core_conf->limit_nproc);
665 req.limits.limit_nproc_set = 1;
668 req.limits.limit_nproc_set = 0;
672#ifdef AP_CGID_USE_RLIMIT
693 const char *description)
742 "Couldn't create unix domain socket");
754 "Couldn't bind unix domain socket %s",
763 "Couldn't set permissions on unix domain socket %s",
770 "Couldn't listen on unix domain socket");
777 "Couldn't change owner of unix domain socket %s",
792 const char *
const *
argv;
821 "Error accepting on cgid socket");
833 "Error reading request on cgid socket");
840 "CGI request received from wrong server instance; "
841 "see ScriptSock directive");
866 "using passed fd %d as stderr",
errfileno);
924 "couldn't set child process attributes: %s",
r->
filename);
951 (
const char *
const *)
env,
955 (
const char *
const *)
env,
965 "couldn't create child process: %d: %s",
rc,
1006 "mod_cgid: Couldn't spawn cgid daemon process");
1019#if APR_HAS_OTHER_CHILD
1064 "The length of the ScriptSock path exceeds maximum, "
1165 return "CGIDScriptTimeout has wrong format";
1173 "the name of a log for script debugging info"),
1175 "the maximum length (in bytes) of the script debug log"),
1177 "the maximum size (in bytes) to record of a POST request"),
1179 "the name of the socket to use for communication with "
1182 "The amount of time to wait between successful reads from "
1183 "the CGI script, in seconds."),
1208 && (finfo.st_size > conf->
logbytes)) ||
1308 APLOGNO(01255),
"unable to create socket to cgi daemon");
1319 "connect #%d to cgi daemon failed, sleeping before retry",
1330 "unable to connect to cgi daemon after multiple tries");
1354 "cgid daemon is gone; is Apache terminating?");
1387 if (
kill(pid, 0) < 0) {
1392 total = total + interval;
1393 if (interval < 500000) {
1407 "CGI process %" APR_PID_T_FMT " didn't exit, sending SIGKILL",
1414 "CGI process %" APR_PID_T_FMT " didn't exit, sending SIGKILL again",
1450 "daemon couldn't find CGI process for connection %lu",
1506 "Options ExecCGI is off in this directory");
1511 "attempt to include NPH CGI script");
1514#if defined(OS2) || defined(WIN32)
1515#error mod_cgid does not work on this platform. If you teach it to, look
1516#error at mod_cgi.c for required code in this path.
1520 "script not found or unable to stat");
1525 "attempt to invoke directory as script");
1533 "AcceptPathInfo off disallows user's path");
1543#ifdef HAVE_CGID_FDPASSING
1547 "could not create pipe for stderr");
1569 "could not send request to cgi daemon");
1587 "failed reading PID from cgi daemon");
1614 "Error reading request entity data");
1625#ifdef HAVE_CGID_FDPASSING
1653 if ((
rr->path_info &&
rr->path_info[0]) ||
rr->args) {
1681 location,
"</a>",
NULL);
1685 f->c->bucket_alloc));
1784 f->c->bucket_alloc));
1792 static const char *
const aszPre[] = {
"mod_include.c",
NULL };
Apache Multi-Processing Module library.
const char apr_size_t len
APR-UTIL Buckets/Bucket Brigades.
APR Miscellaneous library routines.
APR general purpose library routines.
APR-UTIL registration of functions exported by modules.
APR Portability Routines.
APR Standard Headers Support.
static void cgi_optfns_retrieve(void)
static int cgi_handle_response(request_rec *r, int nph, apr_bucket_brigade *bb, apr_interval_time_t timeout, cgi_server_conf *conf, char *logdata, apr_file_t *script_err)
static int log_scripterror(request_rec *r, cgi_server_conf *conf, int ret, apr_status_t rv, const char *logno, const char *error)
static apr_status_t cgi_handle_request(request_rec *r, apr_file_t *script_out, apr_bucket_brigade *bb, char *logbuf, apr_size_t logbufbytes)
static apr_pool_t * pconf
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
char * ap_runtime_dir_relative(apr_pool_t *p, const char *fname)
#define ap_get_module_config(v, m)
ap_conf_vector_t * ap_create_request_config(apr_pool_t *p)
void ap_hook_post_config(ap_HOOK_post_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
struct ap_conf_vector_t ap_conf_vector_t
#define AP_DECLARE_MODULE(foo)
char * ap_server_root_relative(apr_pool_t *p, const char *fname)
void ap_hook_handler(ap_HOOK_handler_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
#define ap_set_module_config(v, m, val)
void ap_hook_pre_config(ap_HOOK_pre_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
request_rec int int apr_table_t const char * path
void ap_hook_optional_fn_retrieve(ap_HOOK_optional_fn_retrieve_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
const char server_rec * main_server
#define AP_SQ_MS_CREATE_PRE_CONFIG
int ap_state_query(int query_code)
#define ap_get_core_module_config(v)
#define AP_CORE_MODULE_INDEX
int ap_allow_options(request_rec *r)
void ap_close_listeners(void)
server_rec * ap_server_conf
const unsigned char * buf
apr_status_t ap_os_create_privileged_process(const request_rec *r, apr_proc_t *newproc, const char *progname, const char *const *args, const char *const *env, apr_procattr_t *attr, apr_pool_t *p)
int ap_map_http_request_error(apr_status_t rv, int status)
void ap_set_content_type_ex(request_rec *r, const char *ct, int trusted)
request_rec * ap_sub_req_lookup_uri(const char *new_uri, const request_rec *r, ap_filter_t *next_filter)
int ap_run_sub_req(request_rec *r)
void ap_destroy_sub_req(request_rec *r)
void ap_add_common_vars(request_rec *r)
char ** ap_create_environment(apr_pool_t *p, apr_table_t *t)
void ap_add_cgi_vars(request_rec *r)
int ap_run_drop_privileges(apr_pool_t *pchild, server_rec *s)
#define APR_OC_REASON_RESTART
#define APR_OC_REASON_LOST
#define APR_OC_REASON_UNREGISTER
#define APR_OC_REASON_DEATH
#define APR_BRIGADE_INSERT_TAIL(b, e)
#define APR_BUCKET_NEXT(e)
#define APR_BRIGADE_SENTINEL(b)
#define APR_BUCKET_IS_EOS(e)
apr_brigade_flush void * ctx
#define APR_BRIGADE_FIRST(b)
#define apr_bucket_read(e, str, len, block)
const char *const * aszPre
#define APR_HOOK_REALLY_FIRST
#define HTTP_SERVICE_UNAVAILABLE
#define HTTP_INTERNAL_SERVER_ERROR
#define ap_is_HTTP_REDIRECT(x)
#define STANDARD20_MODULE_STUFF
char * ap_append_pid(apr_pool_t *p, const char *string, const char *delim)
#define ap_escape_uri(ppool, path)
char * ap_escape_shell_cmd(apr_pool_t *p, const char *s)
#define ap_strchr_c(s, c)
char * ap_make_dirstr_parent(apr_pool_t *p, const char *s)
char * ap_getword_nulls(apr_pool_t *p, const char **line, char stop)
#define ap_escape_html(p, s)
int ap_unescape_url(char *url)
apr_status_t ap_timeout_parameter_parse(const char *timeout_parameter, apr_interval_time_t *timeout, const char *default_time_unit)
const char * ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden)
const char int apr_pool_t * pool
void apr_size_t apr_size_t * bytes_read
#define APR_FPROT_UEXECUTE
int strcasecmp(const char *a, const char *b)
apr_vformatter_buff_t * c
apr_vformatter_buff_t const char va_list ap
char const *const char const *const ** env
apr_sockaddr_t * sockaddr
#define apr_pool_create(newpool, parent)
#define apr_pcalloc(p, size)
const apr_array_header_t * first
apr_int32_t apr_int32_t apr_int32_t err
const char const char *const * args
apr_int64_t apr_interval_time_t
#define apr_time_sec(time)
#define apr_time_from_sec(sec)
apr_status_t ap_mpm_query(int query_code, int *result)
#define AP_MPMQ_MPM_STATE
#define AP_REQ_REJECT_PATH_INFO
static char ** create_argv(apr_pool_t *p, char *path, char *user, char *group, char *av0, const char *args)
static int include_cmd(include_ctx_t *ctx, ap_filter_t *f, apr_bucket_brigade *bb, const char *command)
static apr_socklen_t server_addr_len
static int connect_to_daemon(int *sdptr, request_rec *r, cgid_server_conf *conf)
static void daemon_signal_handler(int sig)
static const char * set_scriptlog_length(cmd_parms *cmd, void *dummy, const char *arg)
static int cgid_start(apr_pool_t *p, server_rec *main_server, apr_proc_t *procnew)
static apr_status_t send_req(int fd, apr_file_t *errpipe, request_rec *r, const char *argv0, char **env, int req_type)
#define DAEMON_STARTUP_ERROR
#define ERRFN_USERDATA_KEY
static const char * set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg)
static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, int *errfd, cgid_req_t *req)
static void register_hook(apr_pool_t *p)
static const char * set_script_socket(cmd_parms *cmd, void *dummy, const char *arg)
static apr_pool_t * root_pool
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)
static const char * set_scriptlog_buffer(cmd_parms *cmd, void *dummy, const char *arg)
static apr_status_t get_cgi_pid(request_rec *r, cgid_server_conf *conf, pid_t *pid)
static int cgid_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
#define DEFAULT_CGID_LISTENBACKLOG
static int cgid_server(void *data)
static void cgid_child_errfn(apr_pool_t *pool, apr_status_t err, const char *description)
static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server)
static struct sockaddr_un * server_addr
static ap_unix_identity_t * cgid_suexec_id_doer(const request_rec *r)
static server_rec * root_server
static apr_status_t dead_yet(pid_t pid, apr_interval_time_t max_wait)
static void * create_cgid_config(apr_pool_t *p, server_rec *s)
static const char * sockname
static int is_scriptaliased(request_rec *r)
static apr_status_t cleanup_script(void *vptr)
static apr_status_t sock_readhdr(int fd, int *errfd, void *vbuf, size_t buf_size)
#define DEFAULT_CONNECT_ATTEMPTS
static void add_ssi_vars(request_rec *r)
static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f, apr_bucket_brigade *bb, char *s)
static const char * set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg)
static int daemon_should_exit
static apr_status_t close_unix_socket(void *thefd)
static void discard_script_output(apr_bucket_brigade *bb)
static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size)
static apr_status_t cleanup_nonchild_process(request_rec *r, pid_t pid)
static void * merge_cgid_config(apr_pool_t *p, void *basev, void *overridesv)
static apr_status_t sock_write(int fd, const void *buf, size_t buf_size)
#define DEFAULT_CONNECT_STARTUP_DELAY
static void * create_cgid_dirconf(apr_pool_t *p, char *dummy)
static const command_rec cgid_cmds[]
static apr_status_t sock_writev(int fd, int auxfd, request_rec *r, int count,...)
static int cgid_handler(request_rec *r)
static ap_unix_identity_t empty_ugid
mod_core private header file
SuExec Extension Module for Apache.
Multi-Processing Modules functions.
scoreboard * ap_scoreboard_image
static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc, step_vars_storage *step_vars)
The representation of a filter chain.
apr_interval_time_t timeout
Structure to store things which are per connection.
struct apr_bucket_alloc_t * bucket_alloc
Per-directory configuration.
Per-request configuration.
A structure that represents the current request.
apr_table_t * err_headers_out
struct ap_conf_vector_t * request_config
apr_table_t * subprocess_env
struct ap_conf_vector_t * per_dir_config
A structure to store information for each virtual server.
apr_interval_time_t timeout
struct ap_conf_vector_t * module_config
apr_status_t apr_ctime(char *date_str, apr_time_t t)
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray