restrict-access.c revision 2692e6870c98132727f0f6800fabf2e6df571781
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmodystatic gid_t primary_gid = (gid_t)-1, privileged_gid = (gid_t)-1;
1d9053f57383a2382c70f76b0790a7bf192aa891Sergey Kitovvoid restrict_access_set_env(const char *user, uid_t uid,
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody env_put(t_strconcat("RESTRICT_USER=", user, NULL));
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody env_put(t_strconcat("RESTRICT_CHROOT=", chroot_dir, NULL));
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody env_put(t_strdup_printf("RESTRICT_SETUID=%s", dec2str(uid)));
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody env_put(t_strdup_printf("RESTRICT_SETGID=%s", dec2str(gid)));
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody env_put(t_strdup_printf("RESTRICT_SETGID_PRIV=%s",
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody if (extra_groups != NULL && *extra_groups != '\0') {
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody env_put(t_strconcat("RESTRICT_SETEXTRAGROUPS=",
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody env_put(t_strdup_printf("RESTRICT_GID_FIRST=%s",
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody env_put(t_strdup_printf("RESTRICT_GID_LAST=%s",
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmodystatic void restrict_init_groups(gid_t primary_gid, gid_t privileged_gid)
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody if (primary_gid == getgid() && primary_gid == getegid()) {
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody /* everything is already set */
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody "gid=%s, egid=%s: %m",
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody if (getegid() != 0 && primary_gid == getgid() &&
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody /* privileged_gid is hopefully in saved ID. if not,
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody there's nothing we can do about it. */
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody if (setresgid(primary_gid, primary_gid, privileged_gid) != 0) {
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody i_fatal("setresgid(%s,%s,%s) failed with euid=%s: %m",
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody if (geteuid() == 0) {
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody /* real, effective, saved -> privileged_gid */
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody /* real, effective -> primary_gid
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody saved -> keep */
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody i_fatal("setregid(%s,%s) failed with euid=%s: %m",
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmodystatic gid_t *get_groups_list(unsigned int *gid_count_r)
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody /* @UNSAFE */
78717e55d8c4b6528d1afe70505a19e4fcc0a56fPhil Carmody if ((ret = getgroups(gid_count, gid_list)) < 0)
bool *have_root_group)
const char *env;
unsigned int i, used;
if (gid_list[i] == 0)
return FALSE;
return TRUE;
unsigned int gid_count;
if (preserve_existing) {
have_root_group) &&
const char *env;
bool allow_root_gid;
/* set the primary/privileged group */
if (is_root) {
T_BEGIN {
} T_END;
time_t t = 0;
(void)localtime(&t);
if (uid != 0) {
if (setuid(0) == 0) {
if (uid == 0)
if (primary_gid == 0)
int restrict_access_use_priv_gid(void)
void restrict_access_drop_priv_gid(void)
if (!using_priv_gid)
bool restrict_access_have_priv_gid(void)