On Sun, 2003-07-13 at 00:58, Matthias Andree wrote:
That's the problem. The home dir is exported by nfs. Chdirs should be done as the user, not as root.
Right.. Well, I'll just ignore that error then:
What if the home directory is owned by another user rather than the real owner? You won't detect that condition any more with the patch.
Hmh.. The reason why I originally added the chdir() there was because unlink_directory() failed to save current working directory so it could be restored. I think it might just as well chdir() to /tmp, except it's also useful for setting directory where core dumps go.
Anyway, home directory isn't required information from auth process. I think I'll chdir to /tmp if it isn't given.
How about this scheme (pseudo code):
seteuid(uid); ret = chdir(targetdir); seteuid(0); if (ret == -1) { /* handle error */ }
Make sure you don't add ANY branches between the seteuid() calls, no mistakes must happen there.
Why? I don't see how dropped privileges can cause much problems. The error handling I would do is just to write to already opened log file and exit(). seteuid() calls also need handling.. How about this:
if (*home_dir != '\0') {
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. 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");
}