From: Timo Sirainen Date: Sat, 12 Jul 2003 23:43:16 +0000 (+0300) Subject: Replaced geteuid() calls with one in the beginning and saving it to X-Git-Tag: 1.1.alpha1~4489 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=54a6d29d96e243cd5c84892384c18c9830359ada;p=thirdparty%2Fdovecot%2Fcore.git Replaced geteuid() calls with one in the beginning and saving it to master_uid. When chdir()ing to user's home dir, temporarily set euid to user's uid. --HG-- branch : HEAD --- diff --git a/src/master/auth-process.c b/src/master/auth-process.c index 7a2732ce22..1c5158bf3a 100644 --- a/src/master/auth-process.c +++ b/src/master/auth-process.c @@ -383,9 +383,10 @@ static void auth_process_group_create(struct auth_settings *auth_set) fd_close_on_exec(group->listen_fd, TRUE); /* set correct permissions */ - if (chown(path, geteuid(), auth_set->parent->defaults->login_gid) < 0) { + if (chown(path, master_uid, + auth_set->parent->defaults->login_gid) < 0) { i_fatal("login: chown(%s, %s, %s) failed: %m", - path, dec2str(geteuid()), + path, dec2str(master_uid), dec2str(auth_set->parent->defaults->login_gid)); } diff --git a/src/master/common.h b/src/master/common.h index ed892cec83..afcd2c6e15 100644 --- a/src/master/common.h +++ b/src/master/common.h @@ -23,6 +23,7 @@ enum { extern struct ioloop *ioloop; extern struct hash_table *pids; extern int null_fd, inetd_login_fd; +extern uid_t master_uid; #define IS_INETD() \ (inetd_login_fd != -1) diff --git a/src/master/mail-process.c b/src/master/mail-process.c index 7fb4f097e2..b4e5f4b4ba 100644 --- a/src/master/mail-process.c +++ b/src/master/mail-process.c @@ -27,7 +27,7 @@ static int validate_uid_gid(struct settings *set, uid_t uid, gid_t gid, return FALSE; } - if (set->login_uid == uid && geteuid() != uid) { + if (set->login_uid == uid && master_uid != uid) { i_error("Can't log in using login processes UID %s (user %s) " "(see login_user in config file).", dec2str(uid), user); @@ -112,7 +112,7 @@ int create_mail_process(struct login_group *group, int socket, const char *addr, *mail, *chroot_dir, *home_dir, *full_home_dir; char title[1024]; pid_t pid; - int i, err; + int i, err, ret; // FIXME: per-group if (mail_process_count == set->max_mail_processes) { @@ -169,9 +169,22 @@ int create_mail_process(struct login_group *group, int socket, full_home_dir = *chroot_dir == '\0' ? home_dir : t_strconcat(chroot_dir, "/", home_dir, NULL); /* NOTE: if home directory is NFS-mounted, we might not - have access to it as root. Ignore such errors. */ - if (chdir(full_home_dir) < 0 && errno != EACCES) - i_fatal("chdir(%s) failed: %m", full_home_dir); + have access to it as root. Change the effective UID + temporarily to make it work. */ + if (reply->uid != master_uid && seteuid(reply->uid) < 0) + i_fatal("seteuid(%s) failed: %m", dec2str(reply->uid)); + ret = chdir(full_home_dir); + if (reply->uid != master_uid && seteuid(master_uid) < 0) + i_fatal("seteuid(%s) failed: %m", dec2str(master_uid)); + if (ret < 0) { + i_fatal("chdir(%s) failed with uid %s: %m", + full_home_dir, dec2str(reply->uid)); + } + } else { + /* We still have to change to some directory where we have + rx-access. /tmp should exist everywhere. */ + if (chdir("/tmp") < 0) + i_fatal("chdir(/tmp) failed: %m"); } env_put("LOGGED_IN=1"); @@ -263,6 +276,7 @@ int create_mail_process(struct login_group *group, int socket, for (i = 0; i < 3; i++) (void)close(i); + errno = err; i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", group->set->mail_executable); diff --git a/src/master/main.c b/src/master/main.c index 3ac34ea2ea..5e778977f9 100644 --- a/src/master/main.c +++ b/src/master/main.c @@ -35,6 +35,7 @@ static struct timeout *to; struct ioloop *ioloop; struct hash_table *pids; int null_fd, inetd_login_fd; +uid_t master_uid; int validate_str(const char *str, size_t max_len) { @@ -444,6 +445,7 @@ int main(int argc, char *argv[]) lib_init(); + master_uid = geteuid(); inetd_login_fd = -1; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-F") == 0) { diff --git a/src/master/master-settings.c b/src/master/master-settings.c index 0ef0c5928a..eccf2a7a80 100644 --- a/src/master/master-settings.c +++ b/src/master/master-settings.c @@ -377,7 +377,7 @@ static int settings_verify(struct settings *set) /* since they're under /var/run by default, they may have been deleted. */ - if (safe_mkdir(set->base_dir, 0700, geteuid(), getegid()) == 0) { + if (safe_mkdir(set->base_dir, 0700, master_uid, getegid()) == 0) { i_warning("Corrected permissions for base directory %s", PKG_RUNDIR); } @@ -388,7 +388,7 @@ static int settings_verify(struct settings *set) return FALSE; } - if (safe_mkdir(set->login_dir, 0750, geteuid(), set->login_gid) == 0) { + if (safe_mkdir(set->login_dir, 0750, master_uid, set->login_gid) == 0) { i_warning("Corrected permissions for login directory %s", set->login_dir); } diff --git a/src/master/ssl-init.c b/src/master/ssl-init.c index 70d942f975..ae6a663ba7 100644 --- a/src/master/ssl-init.c +++ b/src/master/ssl-init.c @@ -86,7 +86,7 @@ static int check_parameters_file_set(struct settings *set) regen_time = st.st_mtime + (time_t)(set->ssl_parameters_regenerate*3600); if (regen_time < ioloop_time || (st.st_mode & 077) != 0 || - st.st_uid != geteuid() || st.st_gid != getegid()) { + st.st_uid != master_uid || st.st_gid != getegid()) { start_generate_process(set); return FALSE; }