]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Replaced geteuid() calls with one in the beginning and saving it to
authorTimo Sirainen <tss@iki.fi>
Sat, 12 Jul 2003 23:43:16 +0000 (02:43 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 12 Jul 2003 23:43:16 +0000 (02:43 +0300)
master_uid. When chdir()ing to user's home dir, temporarily set euid to
user's uid.

--HG--
branch : HEAD

src/master/auth-process.c
src/master/common.h
src/master/mail-process.c
src/master/main.c
src/master/master-settings.c
src/master/ssl-init.c

index 7a2732ce2289ccd85d3b56e9771ef6af49dbfbc3..1c5158bf3aee39795419dd3e3e54b0c504a2446b 100644 (file)
@@ -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));
        }
 
index ed892cec839e17d5f3020a6e0e0c5a2ab0544293..afcd2c6e15fec20b65c03a4684a6ee2062d88e29 100644 (file)
@@ -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)
index 7fb4f097e2f880c9d934817aa3cf449b044f1db0..b4e5f4b4bab391eed49273a2770ecbaeffe245fc 100644 (file)
@@ -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);
 
index 3ac34ea2eace74c96ae16630bd0b52e3cb90f913..5e778977f951368dc7adf7addac3ef068fd2f3eb 100644 (file)
@@ -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) {
index 0ef0c5928a6e5e03c78b715938e86dd4de8171f3..eccf2a7a80a1399de5ef0fe426d822b5cee9b148 100644 (file)
@@ -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);
        }
index 70d942f975724d9e5353ba369074fb76b4177b36..ae6a663ba7b7eb9b2c9e65b78953c4a01e8e3430 100644 (file)
@@ -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;
        }