mod_cgid.c revision 443f96ac390c06ca4fa763d3bfcfbc8f757bd756
6ae232055d4d8a97267517c5e50074c2c819941and/* ====================================================================
6ae232055d4d8a97267517c5e50074c2c819941and * The Apache Software License, Version 1.1
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * Copyright (c) 2000 The Apache Software Foundation. All rights
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * reserved.
6ae232055d4d8a97267517c5e50074c2c819941and * Redistribution and use in source and binary forms, with or without
6ae232055d4d8a97267517c5e50074c2c819941and * modification, are permitted provided that the following conditions
6ae232055d4d8a97267517c5e50074c2c819941and * are met:
6ae232055d4d8a97267517c5e50074c2c819941and * 1. Redistributions of source code must retain the above copyright
6ae232055d4d8a97267517c5e50074c2c819941and * notice, this list of conditions and the following disclaimer.
2e545ce2450a9953665f701bb05350f0d3f26275nd * 2. Redistributions in binary form must reproduce the above copyright
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * notice, this list of conditions and the following disclaimer in
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * the documentation and/or other materials provided with the
6ae232055d4d8a97267517c5e50074c2c819941and * distribution.
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * 3. The end-user documentation included with the redistribution,
3f08db06526d6901aa08c110b5bc7dde6bc39905nd * if any, must include the following acknowledgment:
6ae232055d4d8a97267517c5e50074c2c819941and * "This product includes software developed by the
6ae232055d4d8a97267517c5e50074c2c819941and * Apache Software Foundation (http://www.apache.org/)."
6ae232055d4d8a97267517c5e50074c2c819941and * Alternately, this acknowledgment may appear in the software itself,
b43f840409794ed298e8634f6284741f193b6c4ftakashi * if and wherever such third-party acknowledgments normally appear.
b43f840409794ed298e8634f6284741f193b6c4ftakashi * 4. The names "Apache" and "Apache Software Foundation" must
af84459fbf938e508fd10b01cb8d699c79083813takashi * not be used to endorse or promote products derived from this
6ae232055d4d8a97267517c5e50074c2c819941and * software without prior written permission. For written
f3ec420152ca921e4c1ce77782f51b53f659018dnd * permission, please contact apache@apache.org.
6ae232055d4d8a97267517c5e50074c2c819941and * 5. Products derived from this software may not be called "Apache",
b43f840409794ed298e8634f6284741f193b6c4ftakashi * nor may "Apache" appear in their name, without prior written
b43f840409794ed298e8634f6284741f193b6c4ftakashi * permission of the Apache Software Foundation.
b43f840409794ed298e8634f6284741f193b6c4ftakashi * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
6ae232055d4d8a97267517c5e50074c2c819941and * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
6ae232055d4d8a97267517c5e50074c2c819941and * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6ae232055d4d8a97267517c5e50074c2c819941and * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
6ae232055d4d8a97267517c5e50074c2c819941and * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
6ae232055d4d8a97267517c5e50074c2c819941and * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
6ae232055d4d8a97267517c5e50074c2c819941and * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
6ae232055d4d8a97267517c5e50074c2c819941and * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6ae232055d4d8a97267517c5e50074c2c819941and * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
6ae232055d4d8a97267517c5e50074c2c819941and * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
6ae232055d4d8a97267517c5e50074c2c819941and * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6ae232055d4d8a97267517c5e50074c2c819941and * SUCH DAMAGE.
6ae232055d4d8a97267517c5e50074c2c819941and * ====================================================================
6ae232055d4d8a97267517c5e50074c2c819941and * This software consists of voluntary contributions made by many
6ae232055d4d8a97267517c5e50074c2c819941and * individuals on behalf of the Apache Software Foundation. For more
6ae232055d4d8a97267517c5e50074c2c819941and * information on the Apache Software Foundation, please see
6ae232055d4d8a97267517c5e50074c2c819941and * Portions of this software are based upon public domain software
6ae232055d4d8a97267517c5e50074c2c819941and * originally written at the National Center for Supercomputing Applications,
6ae232055d4d8a97267517c5e50074c2c819941and * University of Illinois, Urbana-Champaign.
6ae232055d4d8a97267517c5e50074c2c819941and * http_script: keeps all script-related ramblings together.
6ae232055d4d8a97267517c5e50074c2c819941and * Compliant to cgi/1.1 spec
6ae232055d4d8a97267517c5e50074c2c819941and * Adapted by rst from original NCSA code by Rob McCool
6ae232055d4d8a97267517c5e50074c2c819941and * Apache adds some new env vars; REDIRECT_URL and REDIRECT_QUERY_STRING for
6ae232055d4d8a97267517c5e50074c2c819941and * custom error responses, and DOCUMENT_ROOT because we found it useful.
6ae232055d4d8a97267517c5e50074c2c819941and * It also adds SERVER_ADMIN - useful for scripts to know who to mail when
6ae232055d4d8a97267517c5e50074c2c819941and * they fail.
6ae232055d4d8a97267517c5e50074c2c819941andstatic void cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server);
6ae232055d4d8a97267517c5e50074c2c819941andstatic int once_through = 0;
6ae232055d4d8a97267517c5e50074c2c819941and/* KLUDGE --- for back-combatibility, we don't have to check Execcgid
6ae232055d4d8a97267517c5e50074c2c819941and * in ScriptAliased directories, which means we need to know if this
6ae232055d4d8a97267517c5e50074c2c819941and * request came through ScriptAlias or not... so the Alias module
6ae232055d4d8a97267517c5e50074c2c819941and * leaves a note for us.
6ae232055d4d8a97267517c5e50074c2c819941and const char *t = apr_table_get(r->notes, "alias-forced-type");
6ae232055d4d8a97267517c5e50074c2c819941and/* Configuration stuff */
6ae232055d4d8a97267517c5e50074c2c819941and/* DEFAULT_CGID_LISTENBACKLOG controls the max depth on the unix socket's
6ae232055d4d8a97267517c5e50074c2c819941and * pending connection queue. If a bunch of cgi requests arrive at about
6ae232055d4d8a97267517c5e50074c2c819941and * the same time, connections from httpd threads/processes will back up
6ae232055d4d8a97267517c5e50074c2c819941and * in the queue while the cgid process slowly forks off a child to process
6ae232055d4d8a97267517c5e50074c2c819941and * each connection on the unix socket. If the queue is too short, the
6ae232055d4d8a97267517c5e50074c2c819941and * httpd process will get ECONNREFUSED when trying to connect.
6ae232055d4d8a97267517c5e50074c2c819941andtypedef struct {
6ae232055d4d8a97267517c5e50074c2c819941and const char *sockname;
6ae232055d4d8a97267517c5e50074c2c819941and const char *logname;
6ae232055d4d8a97267517c5e50074c2c819941and/* If a request includes query info in the URL (stuff after "?"), and
6ae232055d4d8a97267517c5e50074c2c819941and * the query info does not contain "=" (indicative of a FORM submission),
6ae232055d4d8a97267517c5e50074c2c819941and * then this routine is called to create the argument list to be passed
6ae232055d4d8a97267517c5e50074c2c819941and * to the CGI script. When suexec is enabled, the suexec path, user, and
6ae232055d4d8a97267517c5e50074c2c819941and * group are the first three arguments to be passed; if not, all three
6ae232055d4d8a97267517c5e50074c2c819941and * must be NULL. The query info is split into separate arguments, where
6ae232055d4d8a97267517c5e50074c2c819941and * "+" is the separator between keyword arguments.
6ae232055d4d8a97267517c5e50074c2c819941and * XXXX: note that the WIN32 code uses one of the suexec strings
6ae232055d4d8a97267517c5e50074c2c819941and * to pass an interpreter name. Remember this if changing the way they
6ae232055d4d8a97267517c5e50074c2c819941and * are handled in create_argv.
6ae232055d4d8a97267517c5e50074c2c819941andstatic char **create_argv(apr_pool_t *p, char *path, char *user, char *group,
6ae232055d4d8a97267517c5e50074c2c819941and /* count the number of keywords */
6ae232055d4d8a97267517c5e50074c2c819941and numwords = APACHE_ARG_MAX - 5; /* Truncate args to prevent overrun */
6ae232055d4d8a97267517c5e50074c2c819941and av = (char **) apr_palloc(p, (numwords + 5) * sizeof(char *));
6ae232055d4d8a97267517c5e50074c2c819941andstatic int call_exec(request_rec *r, char *argv0, char **env, int shellcmd)
6ae232055d4d8a97267517c5e50074c2c819941and /* the fd on r->server->error_log is closed, but we need somewhere to
6ae232055d4d8a97267517c5e50074c2c819941and * put the error messages from the log_* functions. So, we use stderr,
6ae232055d4d8a97267517c5e50074c2c819941and * since that is better than allowing errors to go unnoticed.
6ae232055d4d8a97267517c5e50074c2c819941and apr_put_os_file(&r->server->error_log, &errfileno, r->pool);
6ae232055d4d8a97267517c5e50074c2c819941and /* TODO: reimplement suexec */
6ae232055d4d8a97267517c5e50074c2c819941and "getpwuid: invalid userid %ld",
6ae232055d4d8a97267517c5e50074c2c819941and "getgrgid: invalid groupid %ld",
6ae232055d4d8a97267517c5e50074c2c819941and else if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) {
727872d18412fc021f03969b8641810d8896820bhumbedooh execle(SHELL_PATH, SHELL_PATH, "-c", argv0, NULL, env);
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh else if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) {
0d0ba3a410038e179b695446bb149cce6264e0abndstatic void cgid_maint(int reason, void *data, apr_wait_t status)
6ae232055d4d8a97267517c5e50074c2c819941and switch (reason) {
case APR_OC_REASON_DEATH:
case APR_OC_REASON_LOST:
case APR_OC_REASON_RESTART:
case APR_OC_REASON_UNREGISTER:
int i, len, j;
unsigned char *data;
char **environ;
void **dconf;
#ifdef RLIMIT_CPU
#ifdef RLIMIT_NPROC
int len;
char *data;
NULL);
for (i =0; env[i]; i++) {
for (i = 0; env[i]; i++) {
#ifdef RLIMIT_CPU
len = 0;
len = 0;
#ifdef RLIMIT_NPROC
len = 0;
char *argv0;
char *filename;
char **env;
apr_pool_t *p;
request_rec *r;
r->pool = p;
int pid;
int errfile;
return errno;
if (rc < 0) {
return errno;
return errno;
if (!geteuid()) {
return errno;
if (sd2 < 0) {
else if (pid == 0) {
if (once_through > 0) {
else if (pid == 0) {
else once_through++;
cgid_server_conf *c =
return NULL;
return NULL;
return NULL;
return NULL;
{NULL}
return ret;
apr_close(f);
return ret;
if (script_err) {
return ret;
&& *dbuf) {
if (script_err) {
if (script_err) {
apr_close(f);
return ret;
int sd;
char **env;
int nbytes;
return DECLINED;
argv0++;
argv0++;
char *newfile;
ap_add_cgi_vars(r);
return retval;
argv0++;
if (ap_should_client_block(r)) {
dbpos = 0;
while ((len_read =
const char *location;
int ret;
return OK;
return HTTP_MOVED_TEMPORARILY;
if (!r->header_only) {
{NULL}
static void register_hook(void)