/*
* ProFTPD - FTP server daemon
* Copyright (c) 1997, 1998 Public Flood Software
* Copyright (c) 2003-2010 The ProFTPD Project team
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* As a special exemption, the copyright holders give permission to link
* this program with OpenSSL and distribute the resulting executable without
* including the source code for OpenSSL in the source distribution.
*/
/* Use Solaris privileges to severely limit root's access. After user
* authentication, this module _completely_ gives up most privileges,
* except for the * bare minimum functionality that is required.
* VERY highly recommended for security-consious admins.
*
* The concept of this was copied from the Linux mod_cap. Solaris
* also has the concept of basic privileges that we can take away to further
* restrict a process lower than what a normal user process can do, this
* module removes some of those as well.
*/
#include <stdio.h>
#include <stdlib.h>
#include <priv.h>
#include "conf.h"
#include "privs.h"
/* Configuration handlers
*/
#define PRIV_SOL_ROOT_PRIVS \
static unsigned int solaris_priv_flags = 0;
unsigned int flags = 0;
config_rec *c = NULL;
register unsigned int i = 0;
/* PRIV_CHOWN is enabled by default. */
cp++;
flags &= ~PRIV_USE_FILE_CHOWN;
} else {
}
}
return PR_HANDLED(cmd);
}
int bool = -1;
config_rec *c = NULL;
if (bool == -1)
*((unsigned char *) c->argv[0]) = bool;
return PR_HANDLED(cmd);
}
/* Command handlers
*/
/* The POST_CMD handler for "PASS" is only called after PASS has
* successfully completed, which means authentication is successful,
* so we can "tweak" our root access down to almost nothing.
*/
priv_set_t *p = NULL;
priv_set_t *i = NULL;
if (!use_privs)
return PR_DECLINED(cmd);
/* If we authenticated as root, we get all appropriate privs */
}
/* The only privilege we need is PRIV_NET_PRIVADDR (bind
* ports < 1024). Everything else can be discarded. We set this
* in the permitted set only, as when we switch away from root
* we lose effective anyhow, and must reset it.
*
* We also remove the basic Solaris privileges we know we will
* never need.
*/
i = priv_allocset();
if (i == NULL)
goto out;
priv_basicset(i);
p = priv_allocset();
if (p == NULL)
goto out;
priv_basicset(p);
if (priv_flags & PRIV_USE_SETID)
/* Add any of the configurable privileges. */
if (priv_flags & PRIV_USE_FILE_CHOWN)
if (priv_flags & PRIV_USE_DAC_READ)
if (priv_flags & PRIV_USE_DAC_WRITE)
if (priv_flags & PRIV_USE_DAC_SEARCH)
if (priv_flags & PRIV_USE_FILE_OWNER)
if (priv_flags & PRIV_DROP_FILE_WRITE)
priv_freeset(i);
priv_freeset(p);
end_login(1);
}
out:
if (i != NULL)
priv_freeset(i);
if (p != NULL)
priv_freeset(p);
if (res != -1) {
/* That's it! Disable all further id switching */
} else {
"privileges failed, reverting to normal operation");
}
return PR_DECLINED(cmd);
}
}
/* Initialization routines
*/
static int solaris_priv_sess_init(void) {
/* Check to see if the lowering of privileges has been disabled in the
* configuration file.
*/
if (use_privs) {
unsigned char *solaris_priv_engine;
if (solaris_priv_engine &&
*solaris_priv_engine == FALSE) {
": lowering of privileges disabled");
}
}
if (use_privs) {
config_rec *c;
if (c != NULL) {
solaris_priv_flags = *((unsigned int *) c->argv[0]);
if (!(solaris_priv_flags & PRIV_USE_FILE_CHOWN)) {
": removing PRIV_CHOWN privilege");
}
if (solaris_priv_flags & PRIV_USE_DAC_READ) {
": adding PRIV_FILE_DAC_READ privilege");
}
if (solaris_priv_flags & PRIV_USE_DAC_WRITE) {
": adding PRIV_FILE_DAC_WRITE privilege");
}
if (solaris_priv_flags & PRIV_USE_DAC_SEARCH) {
": adding PRIV_DAC_SEARCH privilege");
}
if (solaris_priv_flags & PRIV_USE_FILE_OWNER) {
": adding PRIV_FILE_OWNER privilege");
}
}
": removing PRIV_FILE_WRITE basic privilege");
}
/* We also need to check for things which want to revoke root privs
* altogether: mod_exec, mod_sftp, and the RootRevoke directive.
* privileges.
*/
if (use_setuid == FALSE &&
pr_module_exists("mod_sftp.c")) {
if (c &&
use_setuid = TRUE;
}
}
if (use_setuid == FALSE &&
pr_module_exists("mod_exec.c")) {
if (c &&
use_setuid = TRUE;
}
}
if (use_setuid == FALSE) {
if (c &&
use_setuid = TRUE;
}
}
if (use_setuid) {
": adding PRIV_SETID ");
}
}
return 0;
}
static int solaris_priv_module_init(void) {
return 0;
}
/* Module API tables
*/
};
{ 0, NULL }
};
/* Module API version */
0x20,
/* Module name */
"privileges",
/* Module configuration handler table */
/* Module command handler table */
/* Module authentication handler table */
NULL,
/* Module initialization */
/* Session initialization */
/* Module version */
};