dovecot-1.3: Cleaned up restrict_access*() API.
dovecot at dovecot.org
dovecot at dovecot.org
Wed Apr 8 03:49:02 EEST 2009
details: http://hg.dovecot.org/dovecot-1.3/rev/967bfafe6c0a
changeset: 9044:967bfafe6c0a
user: Timo Sirainen <tss at iki.fi>
date: Tue Apr 07 20:48:53 2009 -0400
description:
Cleaned up restrict_access*() API.
diffstat:
13 files changed, 187 insertions(+), 111 deletions(-)
src/auth/main.c | 2
src/deliver/auth-client.c | 2
src/dict/main.c | 2
src/imap/main.c | 2
src/lib/restrict-access.c | 198 ++++++++++++++++++++++----------------
src/lib/restrict-access.h | 44 ++++++--
src/login-common/main.c | 2
src/master/auth-process.c | 10 +
src/master/login-process.c | 11 +-
src/master/mail-process.c | 18 ++-
src/plugins/expire/auth-client.c | 3
src/pop3/main.c | 2
src/util/rawlog.c | 2
diffs (truncated from 574 to 300 lines):
diff -r 126a819f1fa7 -r 967bfafe6c0a src/auth/main.c
--- a/src/auth/main.c Tue Apr 07 18:15:25 2009 -0400
+++ b/src/auth/main.c Tue Apr 07 20:48:53 2009 -0400
@@ -236,7 +236,7 @@ static void drop_privileges(void)
add_extra_listeners();
/* Password lookups etc. may require roots, allow it. */
- restrict_access_by_env(FALSE);
+ restrict_access_by_env(NULL, FALSE);
restrict_access_allow_coredumps(TRUE);
}
diff -r 126a819f1fa7 -r 967bfafe6c0a src/deliver/auth-client.c
--- a/src/deliver/auth-client.c Tue Apr 07 18:15:25 2009 -0400
+++ b/src/deliver/auth-client.c Tue Apr 07 20:48:53 2009 -0400
@@ -141,7 +141,7 @@ int auth_client_lookup_and_restrict(cons
case 1:
if (set_env(&reply, *user, euid) == 0) {
*user = p_strdup(pool, reply.user);
- restrict_access_by_env(TRUE);
+ restrict_access_by_env(getenv("HOME"), TRUE);
ret = EX_OK;
}
break;
diff -r 126a819f1fa7 -r 967bfafe6c0a src/dict/main.c
--- a/src/dict/main.c Tue Apr 07 18:15:25 2009 -0400
+++ b/src/dict/main.c Tue Apr 07 20:48:53 2009 -0400
@@ -57,7 +57,7 @@ static void drop_privileges(void)
sql_drivers_init();
sql_drivers_register_all();
- restrict_access_by_env(FALSE);
+ restrict_access_by_env(NULL, FALSE);
}
static void main_init(void)
diff -r 126a819f1fa7 -r 967bfafe6c0a src/imap/main.c
--- a/src/imap/main.c Tue Apr 07 18:15:25 2009 -0400
+++ b/src/imap/main.c Tue Apr 07 20:48:53 2009 -0400
@@ -159,7 +159,7 @@ static void main_preinit(const struct im
module_dir_load((*set_r)->mail_plugin_dir,
(*set_r)->mail_plugins, TRUE, version);
- restrict_access_by_env(!IS_STANDALONE());
+ restrict_access_by_env(getenv("HOME"), !IS_STANDALONE());
restrict_access_allow_coredumps(TRUE);
}
diff -r 126a819f1fa7 -r 967bfafe6c0a src/lib/restrict-access.c
--- a/src/lib/restrict-access.c Tue Apr 07 18:15:25 2009 -0400
+++ b/src/lib/restrict-access.c Tue Apr 07 20:48:53 2009 -0400
@@ -21,36 +21,15 @@ static gid_t process_privileged_gid = (g
static gid_t process_privileged_gid = (gid_t)-1;
static bool process_using_priv_gid = FALSE;
-void restrict_access_set_env(const char *user, uid_t uid,
- gid_t gid, gid_t privileged_gid,
- const char *chroot_dir,
- gid_t first_valid_gid, gid_t last_valid_gid,
- const char *extra_groups)
-{
- if (user != NULL && *user != '\0')
- env_put(t_strconcat("RESTRICT_USER=", user, NULL));
- if (chroot_dir != NULL && *chroot_dir != '\0')
- env_put(t_strconcat("RESTRICT_CHROOT=", chroot_dir, NULL));
-
- env_put(t_strdup_printf("RESTRICT_SETUID=%s", dec2str(uid)));
- env_put(t_strdup_printf("RESTRICT_SETGID=%s", dec2str(gid)));
- if (privileged_gid != (gid_t)-1) {
- env_put(t_strdup_printf("RESTRICT_SETGID_PRIV=%s",
- dec2str(privileged_gid)));
- }
- if (extra_groups != NULL && *extra_groups != '\0') {
- env_put(t_strconcat("RESTRICT_SETEXTRAGROUPS=",
- extra_groups, NULL));
- }
-
- if (first_valid_gid != 0) {
- env_put(t_strdup_printf("RESTRICT_GID_FIRST=%s",
- dec2str(first_valid_gid)));
- }
- if (last_valid_gid != 0) {
- env_put(t_strdup_printf("RESTRICT_GID_LAST=%s",
- dec2str(last_valid_gid)));
- }
+void restrict_access_init(struct restrict_access_settings *set)
+{
+ memset(set, 0, sizeof(*set));
+
+ set->uid = (uid_t)-1;
+ set->gid = (gid_t)-1;
+ set->privileged_gid = (gid_t)-1;
+ set->first_valid_gid = 0;
+ set->last_valid_gid = (gid_t)-1;
}
static const char *get_uid_str(uid_t uid)
@@ -148,22 +127,17 @@ static gid_t *get_groups_list(unsigned i
return gid_list;
}
-static void drop_restricted_groups(gid_t *gid_list, unsigned int *gid_count,
+static void drop_restricted_groups(const struct restrict_access_settings *set,
+ gid_t *gid_list, unsigned int *gid_count,
bool *have_root_group)
{
/* @UNSAFE */
- gid_t first_valid, last_valid;
- const char *env;
unsigned int i, used;
- env = getenv("RESTRICT_GID_FIRST");
- first_valid = env == NULL ? 0 : (gid_t)strtoul(env, NULL, 10);
- env = getenv("RESTRICT_GID_LAST");
- last_valid = env == NULL ? (gid_t)-1 : (gid_t)strtoul(env, NULL, 10);
-
for (i = 0, used = 0; i < *gid_count; i++) {
- if (gid_list[i] >= first_valid &&
- (last_valid == (gid_t)-1 || gid_list[i] <= last_valid)) {
+ if (gid_list[i] >= set->first_valid_gid &&
+ (set->last_valid_gid == (gid_t)-1 ||
+ gid_list[i] <= set->last_valid_gid)) {
if (gid_list[i] == 0)
*have_root_group = TRUE;
gid_list[used++] = gid_list[i];
@@ -185,7 +159,7 @@ static gid_t get_group_id(const char *na
return group->gr_gid;
}
-static void fix_groups_list(const char *extra_groups,
+static void fix_groups_list(const struct restrict_access_settings *set,
bool preserve_existing, bool *have_root_group)
{
gid_t gid, *gid_list, *gid_list2;
@@ -198,12 +172,12 @@ static void fix_groups_list(const char *
so add it to supplementary groups. */
add_primary_gid = process_privileged_gid != (gid_t)-1;
- tmp = extra_groups == NULL ? &empty :
- t_strsplit_spaces(extra_groups, ", ");
+ tmp = set->extra_groups == NULL ? &empty :
+ t_strsplit_spaces(set->extra_groups, ", ");
if (preserve_existing) {
gid_list = get_groups_list(&gid_count);
- drop_restricted_groups(gid_list, &gid_count,
+ drop_restricted_groups(set, gid_list, &gid_count,
have_root_group);
/* see if the list already contains the primary GID */
for (i = 0; i < gid_count; i++) {
@@ -242,29 +216,25 @@ static void fix_groups_list(const char *
if (setgroups(gid_count, gid_list) < 0) {
if (errno == EINVAL) {
i_fatal("setgroups(%s) failed: Too many extra groups",
- extra_groups == NULL ? "" : extra_groups);
+ set->extra_groups == NULL ? "" :
+ set->extra_groups);
} else {
i_fatal("setgroups() failed: %m");
}
}
}
-void restrict_access_by_env(bool disallow_root)
-{
- const char *env;
- uid_t uid;
+void restrict_access(const struct restrict_access_settings *set,
+ const char *home)
+{
bool is_root, have_root_group, preserve_groups = FALSE;
bool allow_root_gid;
is_root = geteuid() == 0;
/* set the primary/privileged group */
- env = getenv("RESTRICT_SETGID");
- process_primary_gid = env == NULL || *env == '\0' ? (gid_t)-1 :
- (gid_t)strtoul(env, NULL, 10);
- env = getenv("RESTRICT_SETGID_PRIV");
- process_privileged_gid = env == NULL || *env == '\0' ? (gid_t)-1 :
- (gid_t)strtoul(env, NULL, 10);
+ process_primary_gid = set->gid;
+ process_privileged_gid = set->privileged_gid;
have_root_group = process_primary_gid == 0;
if (process_primary_gid != (gid_t)-1 ||
@@ -279,33 +249,32 @@ void restrict_access_by_env(bool disallo
}
/* set system user's groups */
- env = getenv("RESTRICT_USER");
- if (env != NULL && *env != '\0' && is_root) {
- if (initgroups(env, process_primary_gid) < 0) {
+ if (set->system_groups_user != NULL && is_root) {
+ if (initgroups(set->system_groups_user,
+ process_primary_gid) < 0) {
i_fatal("initgroups(%s, %s) failed: %m",
- env, get_gid_str(process_primary_gid));
+ set->system_groups_user,
+ get_gid_str(process_primary_gid));
}
preserve_groups = TRUE;
}
/* add extra groups. if we set system user's groups, drop the
restricted groups at the same time. */
- env = getenv("RESTRICT_SETEXTRAGROUPS");
if (is_root) T_BEGIN {
- fix_groups_list(env, preserve_groups, &have_root_group);
+ fix_groups_list(set, preserve_groups,
+ &have_root_group);
} T_END;
/* chrooting */
- env = getenv("RESTRICT_CHROOT");
- if (env != NULL && *env != '\0') {
+ if (set->chroot_dir != NULL) {
/* kludge: localtime() must be called before chroot(),
or the timezone isn't known */
- const char *home = getenv("HOME");
time_t t = 0;
(void)localtime(&t);
- if (chroot(env) != 0)
- i_fatal("chroot(%s) failed: %m", env);
+ if (chroot(set->chroot_dir) != 0)
+ i_fatal("chroot(%s) failed: %m", set->chroot_dir);
if (home != NULL) {
if (chdir(home) < 0) {
@@ -320,33 +289,30 @@ void restrict_access_by_env(bool disallo
}
/* uid last */
- env = getenv("RESTRICT_SETUID");
- uid = env == NULL || *env == '\0' ? 0 : (uid_t)strtoul(env, NULL, 10);
- if (uid != 0) {
- if (setuid(uid) != 0) {
+ if (set->uid != (uid_t)-1) {
+ if (setuid(set->uid) != 0) {
i_fatal("setuid(%s) failed with euid=%s: %m",
- get_uid_str(uid), get_uid_str(geteuid()));
+ get_uid_str(set->uid), get_uid_str(geteuid()));
}
}
/* verify that we actually dropped the privileges */
- if (uid != 0 || disallow_root) {
+ if (set->uid != (uid_t)-1) {
if (setuid(0) == 0) {
- if (uid == 0)
- i_fatal("Running as root isn't permitted");
+ if (set->uid == 0)
+ i_fatal("This process must not be run as root");
i_fatal("We couldn't drop root privileges");
}
}
- env = getenv("RESTRICT_GID_FIRST");
- if (env != NULL && atoi(env) != 0)
+ if (set->first_valid_gid != 0)
allow_root_gid = FALSE;
else if (process_primary_gid == 0 || process_privileged_gid == 0)
allow_root_gid = TRUE;
else
allow_root_gid = FALSE;
- if (!allow_root_gid && uid != 0) {
+ if (!allow_root_gid && set->uid != 0) {
if (getgid() == 0 || getegid() == 0 || setgid(0) == 0) {
if (process_primary_gid == 0)
i_fatal("GID 0 isn't permitted");
@@ -356,10 +322,80 @@ void restrict_access_by_env(bool disallo
get_gid_str(getgid()), get_gid_str(getegid()));
}
}
+}
+
+void restrict_access_set_env(const struct restrict_access_settings *set)
+{
+ if (set->system_groups_user != NULL &&
+ *set->system_groups_user != '\0') {
+ env_put(t_strconcat("RESTRICT_USER=",
+ set->system_groups_user, NULL));
+ }
+ if (set->chroot_dir != NULL && *set->chroot_dir != '\0')
+ env_put(t_strconcat("RESTRICT_CHROOT=", set->chroot_dir, NULL));
+
+ if (set->uid != (uid_t)-1) {
+ env_put(t_strdup_printf("RESTRICT_SETUID=%s",
+ dec2str(set->uid)));
+ }
+ if (set->gid != (gid_t)-1) {
+ env_put(t_strdup_printf("RESTRICT_SETGID=%s",
+ dec2str(set->gid)));
+ }
+ if (set->privileged_gid != (gid_t)-1) {
+ env_put(t_strdup_printf("RESTRICT_SETGID_PRIV=%s",
+ dec2str(set->privileged_gid)));
More information about the dovecot-cvs
mailing list