i_fatal("Error reading configuration: %s", error);
master_service_init_log(master_service, "anvil: ");
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
anvil_restarted = getenv("ANVIL_RESTARTED") != NULL;
auth_token_init();
/* Password lookups etc. may require roots, allow it. */
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
}
return FATAL_DEFAULT;
master_service_init_log(master_service, "config: ");
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
config_parse_load_modules();
dict_driver_register(&dict_driver_cdb);
#endif
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
}
i_fatal("Invalid value for director_mail_servers setting");
director->orig_config_hosts = mail_hosts_dup(director->mail_hosts);
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
}
return FATAL_DEFAULT;
master_service_init_log(master_service, "dns-client: ");
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
master_service_init_finish(master_service);
static void main_preinit(void)
{
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
}
i_fatal("Error reading configuration: %s", error);
master_service_init_log(master_service, "imap-hibernate: ");
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
imap_clients_init();
(void)master_service_settings_read(master_service,
&input, &output, &error);
}
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
}
int main(int argc, char *argv[])
set = master_service_settings_get(master_service);
master_service_init_log(master_service, "indexer: ");
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
master_service_set_idle_die_callback(master_service, idle_die);
i_fatal("Error reading configuration: %s", error);
master_service_init_log(master_service, "ipc: ");
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
ipc_groups_init();
master_service_init_finish(master_service);
/* if we want to allow root, then we will not drop
root privileges */
- restrict_access(&pclient->set.restrict_set, pclient->set.home,
- !pclient->set.allow_root);
+ restrict_access(&pclient->set.restrict_set,
+ pclient->set.allow_root ? RESTRICT_ACCESS_FLAG_ALLOW_ROOT : 0,
+ pclient->set.home);
exec_child(pclient->path, pclient->args, &pclient->envs,
fd_in[0], fd_out[1], child_extra_fds,
disallow_root = FALSE;
}
if (!setenv_only) {
- restrict_access(&rset, *priv->home == '\0' ? NULL : priv->home,
- disallow_root);
+ restrict_access(&rset, disallow_root ? 0 : RESTRICT_ACCESS_FLAG_ALLOW_ROOT,
+ *priv->home == '\0' ? NULL : priv->home);
} else {
restrict_access_set_env(&rset);
}
}
void restrict_access(const struct restrict_access_settings *set,
- const char *home, bool disallow_root)
+ enum restrict_access_flags flags, const char *home)
{
bool is_root, have_root_group, preserve_groups = FALSE;
bool allow_root_gid;
+ bool allow_root = (flags & RESTRICT_ACCESS_FLAG_ALLOW_ROOT) != 0;
uid_t target_uid = set->uid;
is_root = geteuid() == 0;
}
/* verify that we actually dropped the privileges */
- if ((target_uid != (uid_t)-1 && target_uid != 0) || disallow_root) {
+ if ((target_uid != (uid_t)-1 && target_uid != 0) || !allow_root) {
if (setuid(0) == 0) {
- if (disallow_root &&
+ if (!allow_root &&
(target_uid == 0 || target_uid == (uid_t)-1))
i_fatal("This process must not be run as root");
set_r->chroot_dir = null_if_empty(getenv("RESTRICT_CHROOT"));
}
-void restrict_access_by_env(const char *home, bool disallow_root)
+void restrict_access_by_env(enum restrict_access_flags flags, const char *home)
{
struct restrict_access_settings set;
restrict_access_get_env(&set);
- restrict_access(&set, home, disallow_root);
+ restrict_access(&set, flags, home);
/* clear the environment, so we don't fail if we get back here */
env_remove("RESTRICT_SETUID");
#ifndef RESTRICT_ACCESS_H
#define RESTRICT_ACCESS_H
+enum restrict_access_flags {
+ /* If flags given to restrict_access() include
+ * RESTRICT_ACCESS_FLAG_ALLOW_ROOT, we won't kill
+ * ourself when we have root privileges. */
+ RESTRICT_ACCESS_FLAG_ALLOW_ROOT = 1,
+};
+
struct restrict_access_settings {
/* UID to use, or (uid_t)-1 if you don't want to change it */
uid_t uid;
/* Restrict access as specified by the settings. If home is not NULL,
it's chdir()ed after chrooting, otherwise it chdirs to / (the chroot). */
void restrict_access(const struct restrict_access_settings *set,
- const char *home, bool disallow_root) ATTR_NULL(2);
+ enum restrict_access_flags flags, const char *home)
+ ATTR_NULL(3);
/* Set environment variables so they can be read with
restrict_access_by_env(). */
void restrict_access_set_env(const struct restrict_access_settings *set);
/* Read restrict_access_set_env() environments back into struct. */
void restrict_access_get_env(struct restrict_access_settings *set_r);
/* Read restrictions from environment and call restrict_access().
- If disallow_roots is TRUE, we'll kill ourself if we didn't have the
- environment settings. */
-void restrict_access_by_env(const char *home, bool disallow_root) ATTR_NULL(1);
+ If flags do not include RESTRICT_ACCESS_FLAG_ALLOW_ROOT, we'll kill ourself
+ unless the RESTRICT_* environments caused root privileges to be dropped */
+void restrict_access_by_env(enum restrict_access_flags flags,
+ const char *home) ATTR_NULL(2);
/* Return the chrooted directory if restrict_access*() chrooted,
otherwise NULL. */
if (master_service_settings_read(master_service,
&input, &output, &error) < 0)
i_fatal("Error reading configuration: %s", error);
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
}
static void main_init(void)
verbose_proctitle = master_service_settings_get(master_service)->verbose_proctitle;
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
/* logging should never die if there are some clients */
login_load_modules();
- restrict_access_by_env(NULL, TRUE);
+ restrict_access_by_env(0, NULL);
if (login_debug)
restrict_access_allow_coredumps(TRUE);
initial_service_count = master_service_get_service_count(master_service);
restrict_access_set_env(&rset);
if (service->set->drop_priv_before_exec) {
disallow_root = service->type == SERVICE_TYPE_LOGIN;
- restrict_access(&rset, NULL, disallow_root);
+ restrict_access(&rset,
+ disallow_root ? 0 : RESTRICT_ACCESS_FLAG_ALLOW_ROOT,
+ NULL);
}
}
modules = module_dir_load(STATS_MODULE_DIR, NULL, &mod_set);
module_dir_init(modules);
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
}
static void main_preinit(void)
{
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
}
main_preinit();
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
master_service_init_finish(master_service);
i_fatal("Error reading configuration: %s", error);
master_service_init_log(master_service, "replicator: ");
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
/* finish init before we get list of users from auth, because that
can take long enough for master process to kill us otherwise. */
static void main_preinit(void)
{
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
}
}
i_close_fd(&sfd[1]);
- restrict_access_by_env(getenv("HOME"), TRUE);
+ restrict_access_by_env(0, getenv("HOME"));
process_title_set(t_strdup_printf("[%s:%s rawlog]", getenv("USER"),
dec2str(getppid())));
mail_storage_service_restrict_setenv(service_ctx, user);
/* we can't exec anything in a chroot */
env_remove("RESTRICT_CHROOT");
- restrict_access_by_env(getenv("HOME"), TRUE);
+ restrict_access_by_env(0, getenv("HOME"));
}
if (dup2(fd, STDIN_FILENO) < 0)
if (!drop_to_userdb_privileges &&
(flags & MASTER_SERVICE_FLAG_STANDALONE) == 0) {
/* drop to privileges defined by service settings */
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
}
master_service_init_finish(master_service);
master_service_init_log(master_service, "script: ");
if (argv[0] == NULL)
i_fatal("Missing script path");
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
master_service_init_finish(master_service);
return FATAL_DEFAULT;
master_service_init_log(master_service, "tcpwrap: ");
- restrict_access_by_env(NULL, FALSE);
+ restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
restrict_access_allow_coredumps(TRUE);
master_service_init_finish(master_service);