mod_privileges.c revision 0e05eb961fe93f9ca09c3a6ed9460ba888ca1ba0
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <priv.h>
#include <unistd.h>
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "http_log.h"
#include "mpm_common.h"
#include "ap_mpm.h"
#include "apr_strings.h"
/* TODO - get rid of unixd dependency */
#include "unixd.h"
#define CR_CHECK(x) if (x == -1) \
/* #define BIG_SECURITY_HOLE 1 */
typedef struct {
} priv_cfg;
static priv_set_t *priv_setid;
static int dtrace_enabled = 0;
{
return APR_SUCCESS;
}
{
/* Start at basic privileges all round. */
/* By default, run in secure mode.
* That means dropping basic privileges we don't usually need.
*/
/* Hmmm, should CGI default to secure too ? */
/*
CR_CHECK(priv_delset(cfg->child_priv, PRIV_FILE_LINK_ANY));
CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_INFO));
CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_SESSION));
CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_FORK));
CR_CHECK(priv_delset(cfg->child_priv, PRIV_PROC_EXEC));
*/
/* we´ll use 0 for unset */
/* top-level default_priv wants the top-level cfg */
if (priv_default == NULL) {
}
return cfg;
}
{
request_rec *r = data;
/* ugly hack: grab default uid and gid from unixd */
extern unixd_config_rec ap_unixd_config;
/* if either user or group are not the default, restore them */
}
"Error restoring default userid");
}
"Error restoring default group");
}
}
/* restore default privileges */
"Error restoring default privileges: %s");
}
return APR_SUCCESS;
}
static int privileges_req(request_rec *r)
{
/* cleanup should happen even if something fails part-way through here */
/* set user and group if configured */
}
/* if we should be able to set these but can't, it could be
* a serious security issue. Bail out rather than risk it!
*/
"Error setting userid");
return HTTP_INTERNAL_SERVER_ERROR;
}
"Error setting group");
return HTTP_INTERNAL_SERVER_ERROR;
}
}
/* set vhost's privileges */
"Error setting effective privileges: %s");
return HTTP_INTERNAL_SERVER_ERROR;
}
/* ... including those of any subprocesses */
"Error setting inheritable privileges: %s");
return HTTP_INTERNAL_SERVER_ERROR;
}
"Error setting limit privileges: %s");
return HTTP_INTERNAL_SERVER_ERROR;
}
return OK;
}
#define PDROP_CHECK(x) if (x == -1) { \
return !OK; \
}
{
/* We need to set privileges before mod_unixd,
* 'cos otherwise setuid will wipe our privilege to do so
*/
server_rec *sp;
/* compute ppriv from the union of all the vhosts plus setid */
}
return OK;
}
{
/* Our config stuff has set the privileges we need, so now
* we just set them to those of the parent server_rec
*
* This has to happen after mod_unixd, 'cos mod_unixd needs
* privileges we drop here.
*/
/* defaults - the default vhost */
return OK;
}
{
return APR_SUCCESS;
}
{
server_rec *sp;
/* if we have dtrace enabled, merge it into everything */
if (dtrace_enabled) {
}
}
/* set up priv_setid for per-request use */
priv_setid = priv_allocset();
return !OK;
}
return OK;
}
{
/* refuse to work if the MPM is threaded */
int threaded;
if (rv != APR_SUCCESS) {
"mod_privileges: unable to determine MPM characteristics."
" Please ensure you are using a non-threaded MPM "
"with this module.");
}
if (threaded) {
"mod_privileges is not compatible with a threaded MPM.");
return !OK;
}
return OK;
}
{
}
{
}
return NULL;
}
{
}
return NULL;
}
{
if (!arg) {
/* add basic privileges, excluding those covered by cgimode */
}
return NULL;
}
{
/* default - nothing to do */
}
/* drop fork+exec privs */
}
/* deny privileges to CGI procs */
}
else {
return "VHostCGIMode must be On, Off or Secure";
}
return NULL;
}
{
return err;
}
return NULL;
}
#ifdef BIG_SECURITY_HOLE
{
if (*priv == '-') {
}
else if (*priv == '+') {
}
else {
}
return NULL;
}
{
if (*priv == '-') {
}
else if (*priv == '+') {
}
else {
}
return NULL;
}
#endif
static const command_rec privileges_cmds[] = {
"Userid under which the virtualhost will run"),
"Group under which the virtualhost will run"),
"Run in secure mode (default ON)"),
"Enable fork+exec for this virtualhost (Off|Secure|On)"),
"Enable DTrace"),
#ifdef BIG_SECURITY_HOLE
"Privileges available in the (virtual) server"),
"Privileges available to external programs"),
#endif
{NULL}
};
NULL,
NULL,
NULL,
};