[Dovecot] Permission denied

Timo Sirainen tss at iki.fi
Sun Jul 13 03:30:29 EEST 2003


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




More information about the dovecot mailing list