# specific users in user database by giving /./ in user's home directory
# (eg. /home/./user chroots into /home). Note that usually there is no real
# need to do chrooting, Dovecot doesn't allow users to access files outside
-# their mail directory anyway. <doc/wiki/Chrooting.txt>
+# their mail directory anyway. If your home directories are prefixed with
+# the chroot directory, append "/." to mail_chroot. <doc/wiki/Chrooting.txt>
#mail_chroot =
##
uid_t uid = 0;
gid_t gid = 0;
const char *chroot = getenv("MAIL_CHROOT");
+ const char *home_dir = NULL;
bool debug = getenv("DEBUG") != NULL;
+ unsigned int len;
for (tmp = t_strsplit(args, "\t"); *tmp != NULL; tmp++) {
if (debug)
char *field = i_strdup(*tmp);
if (strncmp(field, "home=", 5) == 0)
- env_put(t_strconcat("HOME=", field + 5, NULL));
+ home_dir = field + 5;
array_append(conn->extra_fields, &field, 1);
}
if (conn->euid == 0 || getegid() != gid)
env_put(t_strconcat("RESTRICT_SETGID=", dec2str(gid), NULL));
- if (chroot != NULL)
+ if (chroot != NULL) {
+ len = strlen(chroot);
+ if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 &&
+ home_dir != NULL &&
+ strncmp(home_dir, chroot, len - 2) == 0) {
+ /* strip chroot dir from home dir */
+ home_dir += len - 2;
+ }
env_put(t_strconcat("RESTRICT_CHROOT=", chroot, NULL));
+ }
+ if (home_dir != NULL)
+ env_put(t_strconcat("HOME=", home_dir, NULL));
extra_groups = getenv("MAIL_EXTRA_GROUPS");
if (extra_groups != NULL) {
uid_t uid;
gid_t gid;
ARRAY_DEFINE(extra_args, const char *);
- unsigned int i, count, left, process_count, throttle;
+ unsigned int i, len, count, left, process_count, throttle;
int ret, log_fd, nice, chdir_errno;
bool home_given, nfs_check;
chroot_dir, user);
return MASTER_LOGIN_STATUS_INTERNAL_ERROR;
}
+ len = strlen(chroot_dir);
+ if (len > 2 && strcmp(chroot_dir + len - 2, "/.") == 0 &&
+ strncmp(home_dir, chroot_dir, len - 2) == 0) {
+ /* strip chroot dir from home dir */
+ home_dir += len - 2;
+ }
if (!dump_capability) {
throttle = set->mail_debug ? 0 :
if (dump_capability)
env_put("DUMP_CAPABILITY=1");
- if (*home_dir == '\0') {
+ if (*home_dir == '\0' && *chroot_dir == '\0') {
full_home_dir = "";
ret = -1;
} else {