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

Properties

Name Value
svn:eol-style native

apache@apache.org
ViewVC Help
Powered by ViewVC 1.1.2