/[Apache-SVN]/httpd/httpd/trunk/modules/arch/unix/mod_privileges.c
ViewVC logotype

Contents of /httpd/httpd/trunk/modules/arch/unix/mod_privileges.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 771145 - (show annotations)
Sun May 3 23:04:02 2009 UTC (6 months, 3 weeks ago) by niq
File MIME type: text/plain
File size: 21411 byte(s)
Whoops!  cleanup r771144, which had some local/dev stuff left in
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 <priv.h>
18 #include <sys/types.h>
19 #include <unistd.h>
20
21 #include "httpd.h"
22 #include "http_config.h"
23 #include "http_protocol.h"
24 #include "http_log.h"
25 #include "mpm_common.h"
26 #include "ap_mpm.h"
27 #include "apr_strings.h"
28
29 /* TODO - get rid of unixd dependency */
30 #include "unixd.h"
31
32 #define CFG_CHECK(x) if (x == -1) return strerror(errno);
33 #define CR_CHECK(x) if (x == -1) \
34 ap_log_error(APLOG_MARK, APLOG_CRIT,0,0, \
35 "Failed to initialise privileges: %s", strerror(errno))
36
37 module AP_MODULE_DECLARE_DATA privileges_module;
38
39 /* #define BIG_SECURITY_HOLE 1 */
40
41 typedef enum { PRIV_UNSET, PRIV_FAST, PRIV_SECURE, PRIV_SELECTIVE } priv_mode;
42
43 typedef struct {
44 priv_set_t *priv;
45 priv_set_t *child_priv;
46 uid_t uid;
47 gid_t gid;
48 priv_mode mode;
49 } priv_cfg;
50
51 typedef struct {
52 priv_mode mode;
53 } priv_dir_cfg;
54
55 static priv_set_t *priv_setid;
56 static priv_set_t *priv_default = NULL;
57 static int dtrace_enabled = 0;
58
59 static apr_status_t priv_cfg_cleanup(void *CFG)
60 {
61 priv_cfg *cfg = CFG;
62 priv_freeset(cfg->priv);
63 priv_freeset(cfg->child_priv);
64 return APR_SUCCESS;
65 }
66 static void *privileges_merge_cfg(apr_pool_t *pool, void *BASE, void *ADD)
67 {
68 /* inherit the mode if it's not set; the rest won't be inherited */
69 priv_cfg *base = BASE;
70 priv_cfg *add = ADD;
71 priv_cfg *ret = apr_pmemdup(pool, add, sizeof(priv_cfg));
72 ret->mode = (add->mode == PRIV_UNSET) ? base->mode : add->mode;
73 return ret;
74 }
75 static void *privileges_create_cfg(apr_pool_t *pool, server_rec *s)
76 {
77 priv_cfg *cfg = apr_palloc(pool, sizeof(priv_cfg));
78
79 /* Start at basic privileges all round. */
80 cfg->priv = priv_str_to_set("basic", ",", NULL);
81 cfg->child_priv = priv_str_to_set("basic", ",", NULL);
82
83 /* By default, run in secure mode.
84 * That means dropping basic privileges we don't usually need.
85 */
86 CR_CHECK(priv_delset(cfg->priv, PRIV_FILE_LINK_ANY));
87 CR_CHECK(priv_delset(cfg->priv, PRIV_PROC_INFO));
88 CR_CHECK(priv_delset(cfg->priv, PRIV_PROC_SESSION));
89
90 /* Hmmm, should CGI default to secure too ? */
91 /*
92 CR_CHECK(priv_delset(cfg->child_priv, PRIV_FILE_LINK_ANY));
93 CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_INFO));
94 CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_SESSION));
95 CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_FORK));
96 CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_EXEC));
97 */
98
99 /* we´ll use 0 for unset */
100 cfg->uid = 0;
101 cfg->gid = 0;
102 cfg->mode = PRIV_UNSET;
103 apr_pool_cleanup_register(pool, cfg, priv_cfg_cleanup,
104 apr_pool_cleanup_null);
105
106 /* top-level default_priv wants the top-level cfg */
107 if (priv_default == NULL) {
108 priv_default = cfg->priv;
109 }
110 return cfg;
111 }
112 static void *privileges_create_dir_cfg(apr_pool_t *pool, char *dummy)
113 {
114 priv_dir_cfg *cfg = apr_palloc(pool, sizeof(priv_dir_cfg));
115 cfg->mode = PRIV_UNSET;
116 return cfg;
117 }
118 static void *privileges_merge_dir_cfg(apr_pool_t *pool, void *BASE, void *ADD)
119 {
120 priv_dir_cfg *base = BASE;
121 priv_dir_cfg *add = ADD;
122 priv_dir_cfg *ret = apr_palloc(pool, sizeof(priv_dir_cfg));
123 ret->mode = (add->mode == PRIV_UNSET) ? base->mode : add->mode;
124 return ret;
125 }
126
127 static apr_status_t privileges_end_req(void *data)
128 {
129 request_rec *r = data;
130 priv_cfg *cfg = ap_get_module_config(r->server->module_config,
131 &privileges_module);
132 priv_dir_cfg *dcfg = ap_get_module_config(r->per_dir_config,
133 &privileges_module);
134
135 /* ugly hack: grab default uid and gid from unixd */
136 extern unixd_config_rec ap_unixd_config;
137
138 /* If we forked a child, we dropped privilege to revert, so
139 * all we can do now is exit
140 */
141 if ((cfg->mode == PRIV_SECURE) ||
142 ((cfg->mode == PRIV_SELECTIVE) && (dcfg->mode == PRIV_SECURE))) {
143 exit(0);
144 }
145
146 /* if either user or group are not the default, restore them */
147 if (cfg->uid || cfg->gid) {
148 if (setppriv(PRIV_ON, PRIV_EFFECTIVE, priv_setid) == -1) {
149 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
150 "PRIV_ON failed restoring default user/group");
151 }
152 if (cfg->uid && (setuid(ap_unixd_config.user_id) == -1)) {
153 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
154 "Error restoring default userid");
155 }
156 if (cfg->gid && (setgid(ap_unixd_config.group_id) == -1)) {
157 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
158 "Error restoring default group");
159 }
160 }
161
162 /* restore default privileges */
163 if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_default) == -1) {
164 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
165 "Error restoring default privileges: %s", strerror(errno));
166 }
167 return APR_SUCCESS;
168 }
169 static int privileges_req(request_rec *r)
170 {
171 /* secure mode: fork a process to handle the request */
172 apr_proc_t proc;
173 apr_status_t rv;
174 int exitcode;
175 apr_exit_why_e exitwhy;
176 int fork_req;
177 priv_cfg *cfg = ap_get_module_config(r->server->module_config,
178 &privileges_module);
179
180 void *breadcrumb = ap_get_module_config(r->request_config,
181 &privileges_module);
182
183 if (!breadcrumb) {
184 /* first call: this is the vhost */
185 fork_req = (cfg->mode == PRIV_SECURE);
186
187 /* set breadcrumb */
188 ap_set_module_config(r->request_config, &privileges_module, &cfg->mode);
189
190 /* If we have per-dir config, defer doing anything */
191 if ((cfg->mode == PRIV_SELECTIVE)) {
192 /* Defer dropping privileges 'til we have a directory
193 * context that'll tell us whether to fork.
194 */
195 return DECLINED;
196 }
197 }
198 else {
199 /* second call is for per-directory. */
200 priv_dir_cfg *dcfg;
201 if ((cfg->mode != PRIV_SELECTIVE)) {
202 /* Our fate was already determined for the vhost -
203 * nothing to do per-directory
204 */
205 return DECLINED;
206 }
207 dcfg = ap_get_module_config(r->per_dir_config, &privileges_module);
208 fork_req = (dcfg->mode == PRIV_SECURE);
209 }
210
211 if (fork_req) {
212 rv = apr_proc_fork(&proc, r->pool);
213 switch (rv) {
214 case APR_INPARENT:
215 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
216 "parent waiting for child");
217 /* FIXME - does the child need to run synchronously?
218 * esp. if we enable mod_privileges with threaded MPMs?
219 * We do need at least to ensure r outlives the child.
220 */
221 rv = apr_proc_wait(&proc, &exitcode, &exitwhy, APR_WAIT);
222 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "parent: child %s",
223 (rv == APR_CHILD_DONE) ? "done" : "notdone");
224
225 /* The child has taken responsibility for reading all input
226 * and sending all output. So we need to bow right out,
227 * and even abandon "normal" housekeeping.
228 */
229 r->eos_sent = 1;
230 apr_table_unset(r->headers_in, "Content-Type");
231 apr_table_unset(r->headers_in, "Content-Length");
232 /* Testing with ab and 100k requests reveals no nasties
233 * so I infer we're not leaking anything like memory
234 * or file descriptors. That's nice!
235 */
236 return DONE;
237 case APR_INCHILD:
238 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "In child!");
239 break; /* now we'll drop privileges in the child */
240 default:
241 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
242 "Failed to fork secure child process!");
243 return HTTP_INTERNAL_SERVER_ERROR;
244 }
245 }
246
247 /* OK, now drop privileges. */
248
249 /* cleanup should happen even if something fails part-way through here */
250 apr_pool_cleanup_register(r->pool, r, privileges_end_req,
251 apr_pool_cleanup_null);
252 /* set user and group if configured */
253 if (cfg->uid || cfg->gid) {
254 if (setppriv(PRIV_ON, PRIV_EFFECTIVE, priv_setid) == -1) {
255 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
256 "No privilege to set user/group");
257 }
258 /* if we should be able to set these but can't, it could be
259 * a serious security issue. Bail out rather than risk it!
260 */
261 if (cfg->uid && (setuid(cfg->uid) == -1)) {
262 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
263 "Error setting userid");
264 return HTTP_INTERNAL_SERVER_ERROR;
265 }
266 if (cfg->gid && (setgid(cfg->gid) == -1)) {
267 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
268 "Error setting group");
269 return HTTP_INTERNAL_SERVER_ERROR;
270 }
271 }
272 /* set vhost's privileges */
273 if (setppriv(PRIV_SET, PRIV_EFFECTIVE, cfg->priv) == -1) {
274 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
275 "Error setting effective privileges: %s", strerror(errno));
276 return HTTP_INTERNAL_SERVER_ERROR;
277 }
278
279 /* ... including those of any subprocesses */
280 if (setppriv(PRIV_SET, PRIV_INHERITABLE, cfg->child_priv) == -1) {
281 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
282 "Error setting inheritable privileges: %s", strerror(errno));
283 return HTTP_INTERNAL_SERVER_ERROR;
284 }
285 if (setppriv(PRIV_SET, PRIV_LIMIT, cfg->child_priv) == -1) {
286 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
287 "Error setting limit privileges: %s", strerror(errno));
288 return HTTP_INTERNAL_SERVER_ERROR;
289 }
290
291 /* If we're in a child process, drop down PPERM too */
292 if (fork_req) {
293 if (setppriv(PRIV_SET, PRIV_PERMITTED, cfg->priv) == -1) {
294 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
295 "Error setting permitted privileges: %s",
296 strerror(errno));
297 return HTTP_INTERNAL_SERVER_ERROR;
298 }
299 }
300
301 return OK;
302 }
303 #define PDROP_CHECK(x) if (x == -1) { \
304 ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, \
305 "Error dropping privileges: %s", strerror(errno)); \
306 return !OK; \
307 }
308
309 static int privileges_drop_first(apr_pool_t *pool, server_rec *s)
310 {
311 /* We need to set privileges before mod_unixd,
312 * 'cos otherwise setuid will wipe our privilege to do so
313 */
314 priv_cfg *spcfg;
315 server_rec *sp;
316 priv_set_t *ppriv = priv_allocset();
317
318 /* compute ppriv from the union of all the vhosts plus setid */
319 priv_copyset(priv_setid, ppriv);
320 for (sp = s; sp != NULL; sp=sp->next) {
321 spcfg = ap_get_module_config(sp->module_config, &privileges_module);
322 priv_union(spcfg->priv, ppriv);
323 }
324 PDROP_CHECK(setppriv(PRIV_SET, PRIV_PERMITTED, ppriv))
325 PDROP_CHECK(setppriv(PRIV_SET, PRIV_EFFECTIVE, ppriv))
326 priv_freeset(ppriv);
327
328 return OK;
329 }
330 static int privileges_drop_last(apr_pool_t *pool, server_rec *s)
331 {
332 /* Our config stuff has set the privileges we need, so now
333 * we just set them to those of the parent server_rec
334 *
335 * This has to happen after mod_unixd, 'cos mod_unixd needs
336 * privileges we drop here.
337 */
338 priv_cfg *cfg = ap_get_module_config(s->module_config, &privileges_module);
339
340 /* defaults - the default vhost */
341 PDROP_CHECK(setppriv(PRIV_SET, PRIV_LIMIT, cfg->child_priv))
342 PDROP_CHECK(setppriv(PRIV_SET, PRIV_INHERITABLE, cfg->child_priv))
343 PDROP_CHECK(setppriv(PRIV_SET, PRIV_EFFECTIVE, cfg->priv))
344
345 return OK;
346 }
347 static apr_status_t privileges_term(void *rec)
348 {
349 priv_freeset(priv_setid);
350 return APR_SUCCESS;
351 }
352 static int privileges_postconf(apr_pool_t *pconf, apr_pool_t *plog,
353 apr_pool_t *ptemp, server_rec *s)
354 {
355 priv_cfg *cfg;
356 server_rec *sp;
357
358 /* if we have dtrace enabled, merge it into everything */
359 if (dtrace_enabled) {
360 for (sp = s; sp != NULL; sp = sp->next) {
361 cfg = ap_get_module_config(sp->module_config, &privileges_module);
362 CR_CHECK(priv_addset(cfg->priv, PRIV_DTRACE_KERNEL));
363 CR_CHECK(priv_addset(cfg->priv, PRIV_DTRACE_PROC));
364 CR_CHECK(priv_addset(cfg->priv, PRIV_DTRACE_USER));
365 CR_CHECK(priv_addset(cfg->child_priv, PRIV_DTRACE_KERNEL));
366 CR_CHECK(priv_addset(cfg->child_priv, PRIV_DTRACE_PROC));
367 CR_CHECK(priv_addset(cfg->child_priv, PRIV_DTRACE_USER));
368 }
369 CR_CHECK(priv_addset(priv_default, PRIV_DTRACE_KERNEL));
370 CR_CHECK(priv_addset(priv_default, PRIV_DTRACE_PROC));
371 CR_CHECK(priv_addset(priv_default, PRIV_DTRACE_USER));
372 }
373
374 /* set up priv_setid for per-request use */
375 priv_setid = priv_allocset();
376 apr_pool_cleanup_register(pconf, NULL, privileges_term,
377 apr_pool_cleanup_null);
378 priv_emptyset(priv_setid);
379 if (priv_addset(priv_setid, PRIV_PROC_SETID) == -1) {
380 ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, ptemp,
381 "priv_addset: %s", strerror(errno));
382 return !OK;
383 }
384 return OK;
385 }
386 static int privileges_init(apr_pool_t *pconf, apr_pool_t *plog,
387 apr_pool_t *ptemp)
388 {
389 /* refuse to work if the MPM is threaded */
390 int threaded;
391 int rv = ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded);
392 if (rv != APR_SUCCESS) {
393 ap_log_perror(APLOG_MARK, APLOG_NOTICE, rv, ptemp,
394 "mod_privileges: unable to determine MPM characteristics."
395 " Please ensure you are using a non-threaded MPM "
396 "with this module.");
397 }
398 if (threaded) {
399 ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, ptemp,
400 "mod_privileges is not compatible with a threaded MPM.");
401 return !OK;
402 }
403 return OK;
404 }
405 static void privileges_hooks(apr_pool_t *pool)
406 {
407 ap_hook_post_read_request(privileges_req, NULL, NULL,
408 APR_HOOK_REALLY_FIRST);
409 ap_hook_header_parser(privileges_req, NULL, NULL, APR_HOOK_REALLY_FIRST);
410 ap_hook_drop_privileges(privileges_drop_first, NULL, NULL, APR_HOOK_FIRST);
411 ap_hook_drop_privileges(privileges_drop_last, NULL, NULL, APR_HOOK_LAST);
412 ap_hook_post_config(privileges_postconf, NULL, NULL, APR_HOOK_MIDDLE);
413 ap_hook_pre_config(privileges_init, NULL, NULL, APR_HOOK_FIRST);
414 }
415
416 static const char *vhost_user(cmd_parms *cmd, void *dir, const char *arg)
417 {
418 priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
419 &privileges_module);
420 cfg->uid = ap_uname2id(arg);
421 if (cfg->uid == 0) {
422 return apr_pstrcat(cmd->pool, "Invalid userid for VHostUser: ",
423 arg, NULL);
424 }
425 return NULL;
426 }
427 static const char *vhost_group(cmd_parms *cmd, void *dir, const char *arg)
428 {
429 priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
430 &privileges_module);
431 cfg->gid = ap_gname2id(arg);
432 if (cfg->uid == 0) {
433 return apr_pstrcat(cmd->pool, "Invalid groupid for VHostGroup: ",
434 arg, NULL);
435 }
436 return NULL;
437 }
438 static const char *vhost_secure(cmd_parms *cmd, void *dir, int arg)
439 {
440 priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
441 &privileges_module);
442 if (!arg) {
443 /* add basic privileges, excluding those covered by cgimode */
444 CFG_CHECK(priv_addset(cfg->priv, PRIV_FILE_LINK_ANY));
445 CFG_CHECK(priv_addset(cfg->priv, PRIV_PROC_INFO));
446 CFG_CHECK(priv_addset(cfg->priv, PRIV_PROC_SESSION));
447 }
448 return NULL;
449 }
450 static const char *vhost_cgimode(cmd_parms *cmd, void *dir, const char *arg)
451 {
452 priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
453 &privileges_module);
454 if (!strcasecmp(arg, "on")) {
455 /* default - nothing to do */
456 }
457 else if (!strcasecmp(arg, "off")) {
458 /* drop fork+exec privs */
459 CFG_CHECK(priv_delset(cfg->priv, PRIV_PROC_FORK));
460 CFG_CHECK(priv_delset(cfg->priv, PRIV_PROC_EXEC));
461 }
462 else if (!strcasecmp(arg, "secure")) {
463 /* deny privileges to CGI procs */
464 CFG_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_FORK));
465 CFG_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_EXEC));
466 CFG_CHECK(priv_delset(cfg->child_priv, PRIV_FILE_LINK_ANY));
467 CFG_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_INFO));
468 CFG_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_SESSION));
469 }
470 else {
471 return "VHostCGIMode must be On, Off or Secure";
472 }
473
474 return NULL;
475 }
476 static const char *dtraceenable(cmd_parms *cmd, void *dir, int arg)
477 {
478 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
479 if (err != NULL) {
480 return err;
481 }
482 dtrace_enabled = arg;
483 return NULL;
484 }
485
486 static const char *privs_mode(cmd_parms *cmd, void *dir, const char *arg)
487 {
488 priv_mode mode = PRIV_UNSET;
489 if (!strcasecmp(arg, "FAST")) {
490 mode = PRIV_FAST;
491 }
492 else if (!strcasecmp(arg, "SECURE")) {
493 mode = PRIV_SECURE;
494 }
495 else if (!strcasecmp(arg, "SELECTIVE")) {
496 mode = PRIV_SELECTIVE;
497 }
498
499 if (cmd->path) {
500 /* In a directory context, set the per_dir_config */
501 priv_dir_cfg *cfg = dir;
502 cfg->mode = mode;
503 if ((mode == PRIV_UNSET) || (mode == PRIV_SELECTIVE)) {
504 return "PrivilegesMode in a Directory context must be FAST or SECURE";
505 }
506 }
507 else {
508 /* In a global or vhost context, set the server config */
509 priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
510 &privileges_module);
511 cfg->mode = mode;
512 if (mode == PRIV_UNSET) {
513 return "PrivilegesMode must be FAST, SECURE or SELECTIVE";
514 }
515 }
516 return NULL;
517 }
518
519 #ifdef BIG_SECURITY_HOLE
520 static const char *vhost_privs(cmd_parms *cmd, void *dir, const char *arg)
521 {
522 priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
523 &privileges_module);
524 const char *priv = arg;
525
526 if (*priv == '-') {
527 CFG_CHECK(priv_delset(cfg->priv, priv+1));
528 }
529 else if (*priv == '+') {
530 CFG_CHECK(priv_addset(cfg->priv, priv+1));
531 }
532 else {
533 priv_emptyset(cfg->priv);
534 CFG_CHECK(priv_addset(cfg->priv, priv));
535 }
536 return NULL;
537 }
538 static const char *vhost_cgiprivs(cmd_parms *cmd, void *dir, const char *arg)
539 {
540 priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
541 &privileges_module);
542 const char *priv = arg;
543 if (*priv == '-') {
544 CFG_CHECK(priv_delset(cfg->child_priv, priv+1));
545 }
546 else if (*priv == '+') {
547 CFG_CHECK(priv_addset(cfg->child_priv, priv+1));
548 }
549 else {
550 priv_emptyset(cfg->child_priv);
551 CFG_CHECK(priv_addset(cfg->child_priv, priv));
552 }
553 return NULL;
554 }
555 #endif
556 static const command_rec privileges_cmds[] = {
557 AP_INIT_TAKE1("VHostUser", vhost_user, NULL, RSRC_CONF,
558 "Userid under which the virtualhost will run"),
559 AP_INIT_TAKE1("VHostGroup", vhost_group, NULL, RSRC_CONF,
560 "Group under which the virtualhost will run"),
561 AP_INIT_FLAG("VHostSecure", vhost_secure, NULL, RSRC_CONF,
562 "Run in enhanced security mode (default ON)"),
563 AP_INIT_TAKE1("VHostCGIMode", vhost_cgimode, NULL, RSRC_CONF,
564 "Enable fork+exec for this virtualhost (Off|Secure|On)"),
565 AP_INIT_FLAG("DTracePrivileges", dtraceenable, NULL, RSRC_CONF,
566 "Enable DTrace"),
567 AP_INIT_TAKE1("PrivilegesMode", privs_mode, NULL, RSRC_CONF|ACCESS_CONF,
568 "tradeoff performance vs security (fast or secure)"),
569 #ifdef BIG_SECURITY_HOLE
570 AP_INIT_ITERATE("VHostPrivs", vhost_privs, NULL, RSRC_CONF,
571 "Privileges available in the (virtual) server"),
572 AP_INIT_ITERATE("VHostCGIPrivs", vhost_cgiprivs, NULL, RSRC_CONF,
573 "Privileges available to external programs"),
574 #endif
575 {NULL}
576 };
577 module AP_MODULE_DECLARE_DATA privileges_module = {
578 STANDARD20_MODULE_STUFF,
579 privileges_create_dir_cfg,
580 privileges_merge_dir_cfg,
581 privileges_create_cfg,
582 privileges_merge_cfg,
583 privileges_cmds,
584 privileges_hooks
585 };

Properties

Name Value
svn:eol-style native

apache@apache.org
ViewVC Help
Powered by ViewVC 1.1.2