mod_netware.c revision 5cbcfb67829b89d261f9a1f16350212b1c776411
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke/* Copyright 2002-2004 The Apache Software Foundation
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke *
9eb6a481980d81a55898ba418fba72fc3c09d8c8Dominik Luecke * Licensed under the Apache License, Version 2.0 (the "License");
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke * you may not use this file except in compliance with the License.
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke * You may obtain a copy of the License at
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke *
2eeec5240b424984e3ee26296da1eeab6c6d739eChristian Maeder * http://www.apache.org/licenses/LICENSE-2.0
b72a390042c19e630cf221494b60c9df2a60d187Dominik Luecke *
b72a390042c19e630cf221494b60c9df2a60d187Dominik Luecke * Unless required by applicable law or agreed to in writing, software
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke * distributed under the License is distributed on an "AS IS" BASIS,
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2af38fde95f93562f2124ec615fba0e509c8202eDominik Luecke * See the License for the specific language governing permissions and
2af38fde95f93562f2124ec615fba0e509c8202eDominik Luecke * limitations under the License.
2af38fde95f93562f2124ec615fba0e509c8202eDominik Luecke */
cf04ba46b9eb495d334466e24e082e391055ca7bDominik Luecke
2af38fde95f93562f2124ec615fba0e509c8202eDominik Luecke#include "apr_strings.h"
2af38fde95f93562f2124ec615fba0e509c8202eDominik Luecke#include "apr_portable.h"
926b3c5491f1c608f5b79e2d8014d7a1385558c3Dominik Luecke#include "apr_buckets.h"
2af38fde95f93562f2124ec615fba0e509c8202eDominik Luecke#include "ap_config.h"
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke#include "httpd.h"
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke#include "http_config.h"
da955132262baab309a50fdffe228c9efe68251dCui Jian#include "http_core.h"
59917a4f0a6a20f5a20bcab1f2a0a0774db56807Dominik Luecke#include "http_protocol.h"
59917a4f0a6a20f5a20bcab1f2a0a0774db56807Dominik Luecke#include "http_request.h"
59917a4f0a6a20f5a20bcab1f2a0a0774db56807Dominik Luecke#include "http_log.h"
59917a4f0a6a20f5a20bcab1f2a0a0774db56807Dominik Luecke#include "util_script.h"
59917a4f0a6a20f5a20bcab1f2a0a0774db56807Dominik Luecke#include "mod_core.h"
59917a4f0a6a20f5a20bcab1f2a0a0774db56807Dominik Luecke#include "apr_optional.h"
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke#include "apr_lib.h"
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke#include "mod_cgi.h"
6e2dba19f0c5ef183c1ac9cf1dff55b9626aeabdDominik Luecke
59917a4f0a6a20f5a20bcab1f2a0a0774db56807Dominik Luecke#ifdef NETWARE
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke
fcac596b16bb10f475066c323b9b1ca44db2b755Dominik Luecke
fcac596b16bb10f475066c323b9b1ca44db2b755Dominik Lueckemodule AP_MODULE_DECLARE_DATA netware_module;
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecketypedef struct {
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke apr_table_t *file_type_handlers; /* CGI map from file types to CGI modules */
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke apr_table_t *file_handler_mode; /* CGI module mode (spawn in same address space or not) */
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke apr_table_t *extra_env_vars; /* Environment variables to be added to the CGI environment */
fcac596b16bb10f475066c323b9b1ca44db2b755Dominik Luecke} netware_dir_config;
fcac596b16bb10f475066c323b9b1ca44db2b755Dominik Luecke
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke
da955132262baab309a50fdffe228c9efe68251dCui Jianstatic void *create_netware_dir_config(apr_pool_t *p, char *dir)
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke{
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke netware_dir_config *new = (netware_dir_config*) apr_palloc(p, sizeof(netware_dir_config));
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke new->file_type_handlers = apr_table_make(p, 10);
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke new->file_handler_mode = apr_table_make(p, 10);
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke new->extra_env_vars = apr_table_make(p, 10);
5b2e9f4673599e1bc6e18a43ad615da28305b8e1Christian Maeder
f90884915ff10ae83f59e709c68824de834e64f5Dominik Luecke apr_table_set(new->file_type_handlers, "NLM", "OS");
b72a390042c19e630cf221494b60c9df2a60d187Dominik Luecke
fcac596b16bb10f475066c323b9b1ca44db2b755Dominik Luecke return new;
fcac596b16bb10f475066c323b9b1ca44db2b755Dominik Luecke}
fcac596b16bb10f475066c323b9b1ca44db2b755Dominik Luecke
da955132262baab309a50fdffe228c9efe68251dCui Jianstatic void *merge_netware_dir_configs(apr_pool_t *p, void *basev, void *addv)
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke{
b72a390042c19e630cf221494b60c9df2a60d187Dominik Luecke netware_dir_config *base = (netware_dir_config *) basev;
da955132262baab309a50fdffe228c9efe68251dCui Jian netware_dir_config *add = (netware_dir_config *) addv;
b72a390042c19e630cf221494b60c9df2a60d187Dominik Luecke netware_dir_config *new = (netware_dir_config *) apr_palloc(p, sizeof(netware_dir_config));
b72a390042c19e630cf221494b60c9df2a60d187Dominik Luecke
b72a390042c19e630cf221494b60c9df2a60d187Dominik Luecke new->file_type_handlers = apr_table_overlay(p, add->file_type_handlers, base->file_type_handlers);
b72a390042c19e630cf221494b60c9df2a60d187Dominik Luecke new->file_handler_mode = apr_table_overlay(p, add->file_handler_mode, base->file_handler_mode);
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke new->extra_env_vars = apr_table_overlay(p, add->extra_env_vars, base->extra_env_vars);
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke return new;
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke}
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke
08056875f5f633ef432598d5245ea41c112d2178Dominik Lueckestatic const char *set_extension_map(cmd_parms *cmd, netware_dir_config *m,
da955132262baab309a50fdffe228c9efe68251dCui Jian char *CGIhdlr, char *ext, char *detach)
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke{
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke int i, len;
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke if (*ext == '.')
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke ++ext;
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke if (CGIhdlr != NULL) {
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke len = strlen(CGIhdlr);
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke for (i=0; i<len; i++) {
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke if (CGIhdlr[i] == '\\') {
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke CGIhdlr[i] = '/';
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke }
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke }
5b2e9f4673599e1bc6e18a43ad615da28305b8e1Christian Maeder }
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke apr_table_set(m->file_type_handlers, ext, CGIhdlr);
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke if (detach) {
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke apr_table_set(m->file_handler_mode, ext, "y");
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke }
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke return NULL;
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke}
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke
08056875f5f633ef432598d5245ea41c112d2178Dominik Lueckestatic apr_status_t ap_cgi_build_command(const char **cmd, const char ***argv,
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke request_rec *r, apr_pool_t *p,
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke cgi_exec_info_t *e_info)
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke{
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke char *ext = NULL;
548f3850942936a8c6021185c8391dfcd3b03018Dominik Luecke char *cmd_only, *ptr;
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke const char *new_cmd;
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke netware_dir_config *d;
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke apr_file_t *fh;
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke const char *args = "";
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke d = (netware_dir_config *)ap_get_module_config(r->per_dir_config,
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke &netware_module);
08056875f5f633ef432598d5245ea41c112d2178Dominik Luecke
fcac596b16bb10f475066c323b9b1ca44db2b755Dominik Luecke if (e_info->process_cgi) {
fcac596b16bb10f475066c323b9b1ca44db2b755Dominik Luecke /* Handle the complete file name, we DON'T want to follow suexec, since
fcac596b16bb10f475066c323b9b1ca44db2b755Dominik Luecke * an unrooted command is as predictable as shooting craps in Win32.
0859769b65851f4c06d6d32fac084b0f4db56c94Christian Maeder *
da955132262baab309a50fdffe228c9efe68251dCui Jian * Notice that unlike most mime extension parsing, we have to use the
4df63f7187b1ba16cbe5c781db187a42f2f49579Dominik Luecke * win32 parsing here, therefore the final extension is the only one
b694e4b3f771a2f32042c9c505dd698bde969558Dominik Luecke * we will consider
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke */
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke *cmd = r->filename;
da955132262baab309a50fdffe228c9efe68251dCui Jian if (r->args && r->args[0] && !ap_strchr_c(r->args, '=')) {
da955132262baab309a50fdffe228c9efe68251dCui Jian args = r->args;
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke }
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke }
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke cmd_only = apr_pstrdup(p, *cmd);
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke e_info->cmd_type = APR_PROGRAM;
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke /* truncate any arguments from the cmd */
da955132262baab309a50fdffe228c9efe68251dCui Jian for (ptr = cmd_only; *ptr && (*ptr != ' '); ptr++);
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke *ptr = '\0';
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke /* Figure out what the extension is so that we can matche it. */
da955132262baab309a50fdffe228c9efe68251dCui Jian ext = strrchr(apr_filepath_name_get(cmd_only), '.');
da955132262baab309a50fdffe228c9efe68251dCui Jian
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke /* If there isn't an extension then give it an empty string */
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke if (!ext) {
da955132262baab309a50fdffe228c9efe68251dCui Jian ext = "";
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke }
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke /* eliminate the '.' if there is one */
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke if (*ext == '.')
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke ++ext;
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke /* check if we have a registered command for the extension*/
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke new_cmd = apr_table_get(d->file_type_handlers, ext);
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke e_info->detached = 1;
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke if (new_cmd == NULL) {
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke "Could not find a command associated with the %s extension", ext);
5b9f5c1b3592b99fc74d3438740ebcf9eb4c94beDominik Luecke return APR_EBADF;
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke }
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke if (stricmp(new_cmd, "OS")) {
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke /* If we have a registered command then add the file that was passed in as a
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke parameter to the registered command. */
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke *cmd = apr_pstrcat (p, new_cmd, " ", cmd_only, NULL);
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke /* Run in its own address space if specified */
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke if(apr_table_get(d->file_handler_mode, ext))
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke e_info->addrspace = 1;
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke }
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke /* Tokenize the full command string into its arguments */
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke apr_tokenize_to_argv(*cmd, (char***)argv, p);
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke /* The first argument should be the executible */
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke *cmd = ap_server_root_relative(p, *argv[0]);
da955132262baab309a50fdffe228c9efe68251dCui Jian
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke return APR_SUCCESS;
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke}
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Lueckestatic void register_hooks(apr_pool_t *p)
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke{
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke APR_REGISTER_OPTIONAL_FN(ap_cgi_build_command);
da955132262baab309a50fdffe228c9efe68251dCui Jian}
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke
da955132262baab309a50fdffe228c9efe68251dCui Jianstatic const command_rec netware_cmds[] = {
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik LueckeAP_INIT_TAKE23("CGIMapExtension", set_extension_map, NULL, OR_FILEINFO,
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke "Full path to the CGI NLM module followed by a file extension. If the "
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke "first parameter is set to \"OS\" then the following file extension is "
da955132262baab309a50fdffe228c9efe68251dCui Jian "treated as NLM. The optional parameter \"detach\" can be specified if "
2ea0ce749d2525f96d5d2f285f519ab07b005b8dDominik Luecke "the NLM should be launched in its own address space."),
{ NULL }
};
module AP_MODULE_DECLARE_DATA netware_module = {
STANDARD20_MODULE_STUFF,
create_netware_dir_config, /* create per-dir config */
merge_netware_dir_configs, /* merge per-dir config */
NULL, /* server config */
NULL, /* merge server config */
netware_cmds, /* command apr_table_t */
register_hooks /* register hooks */
};
#endif