]> granicus.if.org Git - apache/blob - modules/aaa/mod_allowhandlers.c
Fix a comment similar to r1638072
[apache] / modules / aaa / mod_allowhandlers.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "httpd.h"
18 #include "http_config.h"
19 #include "http_request.h"
20 #include "http_log.h"
21
22 module AP_MODULE_DECLARE_DATA allowhandlers_module;
23
24 typedef enum {
25     AH_ALLOW = 0,
26     AH_DENY = 1,
27 } ah_op_e;
28 typedef struct {
29     apr_table_t *handlers;
30     ah_op_e     op;
31 } ah_conf_t;
32
33 static const char * const forbidden_handler = "forbidden";
34 static const char * const no_handler        = "none";
35
36 static int ah_fixups(request_rec *r)
37 {
38     ah_conf_t *conf = ap_get_module_config(r->per_dir_config,
39                                          &allowhandlers_module);
40     int match = 0;
41     const char *handler_name;
42     if (!r->handler || r->handler[0] == '\0') {
43         handler_name = no_handler;
44     }
45     else if (strcasecmp(r->handler, forbidden_handler) == 0) {
46         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
47                       APLOGNO(02398) "Handler 'forbidden' denied by "
48                       "server configuration: URI %s (file %s)",
49                       r->uri, r->filename);
50         return HTTP_FORBIDDEN;
51     }
52     else {
53         handler_name = r->handler;
54     }
55
56     if (!conf)
57         return DECLINED;
58     if (conf->handlers && apr_table_get(conf->handlers, handler_name))
59         match = 1;
60
61     if ((match && conf->op == AH_ALLOW) || (!match && conf->op == AH_DENY)) {
62         return DECLINED;
63     }
64     else {
65         if (handler_name != no_handler) {
66             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
67                           APLOGNO(02399) "Handler '%s' denied by "
68                           "server configuration: URI %s (file %s)",
69                           r->handler, r->uri, r->filename);
70         }
71         else {
72             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
73                           APLOGNO(02400) "Handler denied by server "
74                           "configuration: No handler set for URI %s (file %s)",
75                           r->uri, r->filename);
76         }
77         return HTTP_FORBIDDEN;
78     }
79 }
80
81 static void *ah_create_conf(apr_pool_t * p, char *dummy)
82 {
83   ah_conf_t *conf = apr_pcalloc(p, sizeof(ah_conf_t));
84   conf->op = AH_DENY;
85   return conf;
86 }
87
88 static const char *set_allowed_handlers(cmd_parms *cmd, void *d, int argc, char *const argv[])
89 {
90     int i;
91     ah_conf_t* conf = (ah_conf_t*) d;
92     const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
93     if (err)
94         return err;
95     if (argc == 0)
96         return "AllowHandlers: No handler name given";
97     conf->op = AH_ALLOW;
98     if (conf->handlers)
99         apr_table_clear(conf->handlers);
100     for (i = 0; i < argc; i++) {
101         if (strcasecmp(argv[i], forbidden_handler) == 0 && conf->op != AH_DENY)
102             return "Handler name 'forbidden' cannot be changed.";
103         if (strcasecmp(argv[i], "all") == 0) {
104             if (argc != 1)
105                 return "'all' not possible with specific handler names";
106             conf->op = AH_DENY;
107             return NULL;
108         }
109         else if (strcasecmp(argv[i], "not") == 0) {
110             if (i != 0 || argc == 1)
111                 return "'not' must come before specific handler names";
112             conf->op = AH_DENY;
113         }
114         else {
115             if (!conf->handlers)
116                 conf->handlers = apr_table_make(cmd->pool, 4);
117             apr_table_setn(conf->handlers, argv[i], "1");
118         }
119     }
120     return NULL;
121 }
122
123 static void ah_register_hooks(apr_pool_t * p)
124 {
125     ap_hook_fixups(ah_fixups, NULL, NULL, APR_HOOK_REALLY_LAST);
126 }
127
128 static const command_rec ah_cmds[] = {
129     AP_INIT_TAKE_ARGV("AllowHandlers", set_allowed_handlers, NULL, ACCESS_CONF,
130                       "only allow specific handlers (use 'not' to negate)"),
131   {NULL}
132 };
133
134 AP_DECLARE_MODULE(allowhandlers) = {
135   STANDARD20_MODULE_STUFF,
136   ah_create_conf,
137   NULL,
138   NULL,
139   NULL,
140   ah_cmds,
141   ah_register_hooks,
142 };
143