dovecot-2.0: mail storage service: Fixed chroot handling.

dovecot at dovecot.org dovecot at dovecot.org
Tue Apr 13 13:28:11 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/9d4a9abf3ec3
changeset: 11136:9d4a9abf3ec3
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Apr 13 13:28:08 2010 +0300
description:
mail storage service: Fixed chroot handling.

diffstat:

 src/lib-storage/mail-storage-service.c |  59 ++++++++++++++++++++---------
 1 files changed, 40 insertions(+), 19 deletions(-)

diffs (97 lines):

diff -r 7d541fcfcb5e -r 9d4a9abf3ec3 src/lib-storage/mail-storage-service.c
--- a/src/lib-storage/mail-storage-service.c	Tue Apr 13 13:24:31 2010 +0300
+++ b/src/lib-storage/mail-storage-service.c	Tue Apr 13 13:28:08 2010 +0300
@@ -296,6 +296,7 @@
 {
 	struct restrict_access_settings rset;
 	uid_t current_euid, setuid_uid = 0;
+	const char *cur_chroot;
 
 	current_euid = geteuid();
 	restrict_access_init(&rset);
@@ -349,6 +350,23 @@
 	rset.chroot_dir = *chroot == '\0' || keep_setuid_root ? NULL : chroot;
 	rset.system_groups_user = system_groups_user;
 
+	cur_chroot = restrict_access_get_current_chroot();
+	if (cur_chroot != NULL) {
+		if (rset.chroot_dir == NULL) {
+			*error_r = "Process is already chrooted, "
+				"can't un-chroot for this user";
+			return -1;
+		}
+		if (strcmp(rset.chroot_dir, cur_chroot) != 0) {
+			*error_r = t_strdup_printf(
+				"Process is already chrooted to %s, "
+				"can't chroot to %s", cur_chroot, chroot);
+			return -1;
+		}
+		/* chrooting to same directory where we're already chrooted */
+		rset.chroot_dir = NULL;
+	}
+
 	if (disallow_root &&
 	    (rset.uid == 0 || (rset.uid == (uid_t)-1 && current_euid == 0))) {
 		*error_r = "Mail access not allowed for root";
@@ -753,7 +771,7 @@
 
 	user->set_parser = settings_parser_dup(set_parser, user_pool);
 	if (!settings_parser_check(user->set_parser, user_pool, &error))
-		i_unreached();
+		i_panic("settings_parser_check() failed: %s", error);
 
 	user->user_set = settings_parser_get_list(user->set_parser)[1];
 
@@ -810,6 +828,27 @@
 		return -2;
 	}
 
+	len = strlen(chroot);
+	if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 &&
+	    strncmp(home, chroot, len - 2) == 0) {
+		/* mail_chroot = /chroot/. means that the home dir already
+		   contains the chroot dir. remove it from home. */
+		if (!temp_priv_drop) {
+			home += len - 2;
+			if (*home == '\0')
+				home = "/";
+			chroot = t_strndup(chroot, len - 2);
+
+			set_keyval(ctx, user, "mail_home", home);
+			set_keyval(ctx, user, "mail_chroot", chroot);
+		}
+	} else if (len > 0 && temp_priv_drop) {
+		/* we're dropping privileges only temporarily, so we can't
+		   chroot. fix home directory so we can access it. */
+		set_keyval(ctx, user, "mail_home",
+			   t_strconcat(chroot, "/", home, NULL));
+	}
+
 	if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0)
 		mail_storage_service_init_log(ctx->service, user);
 
@@ -830,24 +869,6 @@
 	   initialized yet. */
 	module_dir_init(mail_storage_service_modules);
 
-	/* we couldn't do chrooting, so if chrooting was enabled fix
-	   the home directory */
-	len = strlen(chroot);
-	if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 &&
-	    strncmp(home, chroot, len - 2) == 0) {
-		/* home dir already contains the chroot dir */
-		if (!temp_priv_drop) {
-			home += len - 2;
-			if (*home == '\0')
-				home = "/";
-
-			set_keyval(ctx, user, "mail_home", home);
-			chroot = t_strndup(chroot, len - 2);
-		}
-	} else if (len > 0 && temp_priv_drop) {
-		set_keyval(ctx, user, "mail_home",
-			   t_strconcat(chroot, "/", home, NULL));
-	}
 	if (mail_storage_service_init_post(ctx, user, home,
 					   mail_user_r, &error) < 0) {
 		i_error("user %s: Initialization failed: %s",


More information about the dovecot-cvs mailing list