dovecot-1.1: mbox: Give better error messages if dotlocking fails.

dovecot at dovecot.org dovecot at dovecot.org
Thu Feb 26 20:55:49 EET 2009


details:   http://hg.dovecot.org/dovecot-1.1/rev/51f4b25c7bd3
changeset: 8174:51f4b25c7bd3
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Feb 26 13:55:37 2009 -0500
description:
mbox: Give better error messages if dotlocking fails.

diffstat:

1 file changed, 63 insertions(+), 16 deletions(-)
src/lib-storage/index/mbox/mbox-lock.c |   79 +++++++++++++++++++++++++-------

diffs (148 lines):

diff -r 2c7111b2b0d0 -r 51f4b25c7bd3 src/lib-storage/index/mbox/mbox-lock.c
--- a/src/lib-storage/index/mbox/mbox-lock.c	Thu Feb 26 11:24:21 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-lock.c	Thu Feb 26 13:55:37 2009 -0500
@@ -14,6 +14,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#include <grp.h>
 
 #ifdef HAVE_FLOCK
 #  include <sys/file.h>
@@ -260,7 +261,7 @@ static int mbox_dotlock_privileged_op(st
 				      enum mbox_dotlock_op op)
 {
 	const char *dir, *fname;
-	int ret = -1, orig_dir_fd;
+	int ret = -1, orig_dir_fd, orig_errno;
 
 	orig_dir_fd = open(".", O_RDONLY);
 	if (orig_dir_fd == -1) {
@@ -307,29 +308,73 @@ static int mbox_dotlock_privileged_op(st
 		ret = file_dotlock_create(set, fname, 0, &mbox->mbox_dotlock);
 		if (ret > 0)
 			mbox->mbox_used_privileges = TRUE;
+		else if (ret < 0 && errno == EACCES) {
+			const char *errmsg = mail_storage_create_eacces_msg(
+						"file_dotlock_create", fname);
+			mail_storage_set_critical(&mbox->storage->storage,
+						  "%s", errmsg);
+		} else {
+			mbox_set_syscall_error(mbox, "file_dotlock_create()");
+		}
 		break;
 	case MBOX_DOTLOCK_OP_UNLOCK:
 		/* we're now privileged - avoid doing as much as possible */
 		ret = file_dotlock_delete(&mbox->mbox_dotlock);
+		if (ret < 0)
+			mbox_set_syscall_error(mbox, "file_dotlock_delete()");
 		mbox->mbox_used_privileges = FALSE;
 		break;
 	case MBOX_DOTLOCK_OP_TOUCH:
 		if (!file_dotlock_is_locked(mbox->mbox_dotlock)) {
-			file_dotlock_delete(&mbox->mbox_dotlock);
+			if (file_dotlock_delete(&mbox->mbox_dotlock) < 0) {
+				mbox_set_syscall_error(mbox,
+						       "file_dotlock_delete()");
+			}
 			mbox->mbox_used_privileges = TRUE;
 			ret = -1;
 		} else {
 			ret = file_dotlock_touch(mbox->mbox_dotlock);
+			if (ret < 0) {
+				mbox_set_syscall_error(mbox,
+						       "file_dotlock_touch()");
+			}
 		}
 		break;
 	}
 
+	orig_errno = errno;
 	restrict_access_drop_priv_gid();
 
 	if (fchdir(orig_dir_fd) < 0)
 		i_error("fchdir() failed: %m");
 	(void)close(orig_dir_fd);
+	errno = orig_errno;
 	return ret;
+}
+
+static void
+mbox_dotlock_log_eacces_error(struct mbox_mailbox *mbox, const char *path)
+{
+	const char *dir, *errmsg;
+	struct stat st;
+	const struct group *group;
+	int orig_errno = errno;
+
+	errmsg = mail_storage_create_eacces_msg("file_dotlock_create", path);
+	dir = strrchr(path, '/');
+	dir = dir == NULL ? "." : t_strdup_until(path, dir);
+	if (stat(dir, &st) == 0 &&
+	    (st.st_mode & 02) == 0 && /* not world-writable */
+	    (st.st_mode & 020) != 0) { /* group-writable */
+		group = getgrgid(st.st_gid);
+		mail_storage_set_critical(&mbox->storage->storage,
+			"%s (set mail_privileged_group=%s)", errmsg,
+			group == NULL ? dec2str(st.st_gid) : group->gr_name);
+	} else {
+		mail_storage_set_critical(&mbox->storage->storage,
+			"%s (nonstandard permissions in %s)", errmsg, path);
+	}
+	errno = orig_errno;
 }
 
 static int
@@ -343,17 +388,16 @@ mbox_lock_dotlock_int(struct mbox_lock_c
 		if (!mbox->mbox_dotlocked)
 			return 1;
 
-		if (!mbox->mbox_used_privileges)
-			ret = file_dotlock_delete(&mbox->mbox_dotlock);
-		else {
+		if (!mbox->mbox_used_privileges) {
+			if (file_dotlock_delete(&mbox->mbox_dotlock) <= 0) {
+				mbox_set_syscall_error(mbox,
+						       "file_dotlock_delete()");
+			}
+		} else {
 			ctx->using_privileges = TRUE;
-			ret = mbox_dotlock_privileged_op(mbox, NULL,
-							MBOX_DOTLOCK_OP_UNLOCK);
+			(void)mbox_dotlock_privileged_op(mbox, NULL,
+							 MBOX_DOTLOCK_OP_UNLOCK);
 			ctx->using_privileges = FALSE;
-		}
-		if (ret <= 0) {
-			mbox_set_syscall_error(mbox, "file_dotlock_delete()");
-			ret = -1;
 		}
                 mbox->mbox_dotlocked = FALSE;
 		return 1;
@@ -375,18 +419,21 @@ mbox_lock_dotlock_int(struct mbox_lock_c
 	set.context = ctx;
 
 	ret = file_dotlock_create(&set, mbox->path, 0, &mbox->mbox_dotlock);
-	if (ret < 0 && errno == EACCES && restrict_access_have_priv_gid() &&
-	    mbox->mbox_privileged_locking) {
+	if (ret >= 0) {
+		/* success / timeout */
+	} else if (errno == EACCES && restrict_access_have_priv_gid() &&
+		   mbox->mbox_privileged_locking) {
 		/* try again, this time with extra privileges */
 		ret = mbox_dotlock_privileged_op(mbox, &set,
 						 MBOX_DOTLOCK_OP_LOCK);
-	}
+	} else if (errno == EACCES)
+		mbox_dotlock_log_eacces_error(mbox, mbox->path);
+	else
+		mbox_set_syscall_error(mbox, "file_dotlock_create()");
 
 	if (ret < 0) {
 		if ((ENOSPACE(errno) || errno == EACCES) && try)
 			return 1;
-
-		mbox_set_syscall_error(mbox, "file_lock_dotlock()");
 		return -1;
 	}
 	if (ret == 0) {


More information about the dovecot-cvs mailing list