/[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 - (hide 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 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     #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 niq 771144 typedef enum { PRIV_UNSET, PRIV_FAST, PRIV_SECURE, PRIV_SELECTIVE } priv_mode;
42    
43 niq 713961 typedef struct {
44     priv_set_t *priv;
45     priv_set_t *child_priv;
46     uid_t uid;
47     gid_t gid;
48 niq 771144 priv_mode mode;
49 niq 713961 } priv_cfg;
50    
51 niq 771144 typedef struct {
52     priv_mode mode;
53     } priv_dir_cfg;
54    
55 niq 713961 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 niq 771144 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 niq 713961 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 niq 771144 cfg->mode = PRIV_UNSET;
103 niq 713961 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 niq 771144 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 niq 713961
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 niq 771144 priv_dir_cfg *dcfg = ap_get_module_config(r->per_dir_config,
133     &privileges_module);
134 niq 713961
135     /* ugly hack: grab default uid and gid from unixd */
136 covener 723078 extern unixd_config_rec ap_unixd_config;
137 niq 713961
138 niq 771144 /* 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 niq 713961 /* 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 covener 723078 if (cfg->uid && (setuid(ap_unixd_config.user_id) == -1)) {
153 niq 713961 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
154     "Error restoring default userid");
155     }
156 covener 723078 if (cfg->gid && (setgid(ap_unixd_config.group_id) == -1)) {
157 niq 713961 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 niq 738526 "Error restoring default privileges: %s", strerror(errno));
166 niq 713961 }
167     return APR_SUCCESS;
168     }
169     static int privileges_req(request_rec *r)
170     {
171 niq 771144 /* 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 niq 713961 priv_cfg *cfg = ap_get_module_config(r->server->module_config,
178     &privileges_module);
179    
180 niq 771144 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 niq 713961 /* 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 niq 738526 "Error setting effective privileges: %s", strerror(errno));
276 niq 713961 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 niq 738526 "Error setting inheritable privileges: %s", strerror(errno));
283 niq 713961 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 niq 738526 "Error setting limit privileges: %s", strerror(errno));
288 niq 713961 return HTTP_INTERNAL_SERVER_ERROR;
289     }
290    
291 niq 771144 /* 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 niq 713961 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 niq 738526 "priv_addset: %s", strerror(errno));
382 niq 713961 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 niq 771144 ap_hook_header_parser(privileges_req, NULL, NULL, APR_HOOK_REALLY_FIRST);
410 niq 713961 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 niq 771144 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 niq 713961 #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 niq 771144 "Run in enhanced security mode (default ON)"),
563 niq 713961 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 niq 771144 AP_INIT_TAKE1("PrivilegesMode", privs_mode, NULL, RSRC_CONF|ACCESS_CONF,
568     "tradeoff performance vs security (fast or secure)"),
569 niq 713961 #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 niq 771144 privileges_create_dir_cfg,
580     privileges_merge_dir_cfg,
581 niq 713961 privileges_create_cfg,
582 niq 771144 privileges_merge_cfg,
583 niq 713961 privileges_cmds,
584     privileges_hooks
585     };

Properties

Name Value
svn:eol-style native

apache@apache.org
ViewVC Help
Powered by ViewVC 1.1.2