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