Skip to content

Commit

Permalink
lib: Add restrict_access_flags enum to use with restrict_access[_by_e…
Browse files Browse the repository at this point in the history
…nv]()

Swap parameter locations in the functions to make sure plugins are
updated to use the new api.
  • Loading branch information
mrannanj authored and sirainen committed Feb 12, 2018
1 parent de0034c commit 816d20b
Show file tree
Hide file tree
Showing 28 changed files with 51 additions and 38 deletions.
2 changes: 1 addition & 1 deletion src/anvil/main.c
Expand Up @@ -65,7 +65,7 @@ int main(int argc, char *argv[])
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;

Expand Down
2 changes: 1 addition & 1 deletion src/auth/main.c
Expand Up @@ -209,7 +209,7 @@ static void main_preinit(void)
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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/config/main.c
Expand Up @@ -23,7 +23,7 @@ int main(int argc, char *argv[])
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();
Expand Down
2 changes: 1 addition & 1 deletion src/dict/main.c
Expand Up @@ -82,7 +82,7 @@ static void main_preinit(void)
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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/director/main.c
Expand Up @@ -291,7 +291,7 @@ static void main_preinit(void)
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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/dns/dns-client.c
Expand Up @@ -135,7 +135,7 @@ int main(int argc, char *argv[])
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);
Expand Down
2 changes: 1 addition & 1 deletion src/doveadm/main.c
Expand Up @@ -64,7 +64,7 @@ void help_ver2(const struct doveadm_cmd_ver2 *cmd)

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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/imap-hibernate/main.c
Expand Up @@ -39,7 +39,7 @@ int main(int argc, char *argv[])
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();
Expand Down
2 changes: 1 addition & 1 deletion src/indexer/indexer-worker.c
Expand Up @@ -40,7 +40,7 @@ static void drop_privileges(void)
(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[])
Expand Down
2 changes: 1 addition & 1 deletion src/indexer/indexer.c
Expand Up @@ -122,7 +122,7 @@ 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);

Expand Down
2 changes: 1 addition & 1 deletion src/ipc/main.c
Expand Up @@ -46,7 +46,7 @@ int main(int argc, char *argv[])
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);
Expand Down
5 changes: 3 additions & 2 deletions src/lib-program-client/program-client-local.c
Expand Up @@ -235,8 +235,9 @@ int program_client_local_connect(struct program_client *pclient)

/* 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,
Expand Down
4 changes: 2 additions & 2 deletions src/lib-storage/mail-storage-service.c
Expand Up @@ -640,8 +640,8 @@ service_drop_privileges(struct mail_storage_service_user *user,
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);
}
Expand Down
11 changes: 6 additions & 5 deletions src/lib/restrict-access.c
Expand Up @@ -256,10 +256,11 @@ get_setuid_error_str(const struct restrict_access_settings *set, uid_t target_ui
}

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;
Expand Down Expand Up @@ -345,9 +346,9 @@ void restrict_access(const struct restrict_access_settings *set,
}

/* 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");

Expand Down Expand Up @@ -448,12 +449,12 @@ void restrict_access_get_env(struct restrict_access_settings *set_r)
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");
Expand Down
17 changes: 13 additions & 4 deletions src/lib/restrict-access.h
@@ -1,6 +1,13 @@
#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;
Expand Down Expand Up @@ -37,16 +44,18 @@ void restrict_access_init(struct restrict_access_settings *set);
/* 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. */
Expand Down
2 changes: 1 addition & 1 deletion src/lmtp/main.c
Expand Up @@ -63,7 +63,7 @@ static void drop_privileges(void)
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)
Expand Down
2 changes: 1 addition & 1 deletion src/log/main.c
Expand Up @@ -79,7 +79,7 @@ int main(int argc, char *argv[])

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 */
Expand Down
2 changes: 1 addition & 1 deletion src/login-common/main.c
Expand Up @@ -428,7 +428,7 @@ static void main_preinit(void)

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);
Expand Down
4 changes: 3 additions & 1 deletion src/master/service-process.c
Expand Up @@ -193,7 +193,9 @@ drop_privileges(struct service *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);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/old-stats/main.c
Expand Up @@ -38,7 +38,7 @@ static void main_preinit(void)
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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/quota/quota-status.c
Expand Up @@ -204,7 +204,7 @@ static const struct connection_vfuncs client_vfuncs = {

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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/replication/aggregator/aggregator.c
Expand Up @@ -61,7 +61,7 @@ int main(int argc, char *argv[])

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);

Expand Down
2 changes: 1 addition & 1 deletion src/replication/replicator/replicator.c
Expand Up @@ -102,7 +102,7 @@ int main(int argc, char *argv[])
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. */
Expand Down
2 changes: 1 addition & 1 deletion src/stats/main.c
Expand Up @@ -42,7 +42,7 @@ static void client_connected(struct master_service_connection *conn)

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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/util/rawlog.c
Expand Up @@ -356,7 +356,7 @@ static void rawlog_open(enum rawlog_flags flags)
}
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())));
Expand Down
4 changes: 2 additions & 2 deletions src/util/script-login.c
Expand Up @@ -121,7 +121,7 @@ static void client_connected(struct master_service_connection *conn)
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)
Expand Down Expand Up @@ -217,7 +217,7 @@ int main(int argc, char *argv[])
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);
Expand Down
2 changes: 1 addition & 1 deletion src/util/script.c
Expand Up @@ -269,7 +269,7 @@ int main(int argc, char *argv[])
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);
Expand Down
2 changes: 1 addition & 1 deletion src/util/tcpwrap.c
Expand Up @@ -114,7 +114,7 @@ int main(int argc, char *argv[])
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);
Expand Down

0 comments on commit 816d20b

Please sign in to comment.