dovecot-1.2: mbox: Give better error messages if dotlocking fails.
dovecot at dovecot.org
dovecot at dovecot.org
Thu Feb 26 20:54:36 EET 2009
details: http://hg.dovecot.org/dovecot-1.2/rev/f3ce7c7c0b58
changeset: 8783:f3ce7c7c0b58
user: Timo Sirainen <tss at iki.fi>
date: Thu Feb 26 13:54:30 2009 -0500
description:
mbox: Give better error messages if dotlocking fails.
diffstat:
1 file changed, 65 insertions(+), 16 deletions(-)
src/lib-storage/index/mbox/mbox-lock.c | 81 +++++++++++++++++++++++++-------
diffs (159 lines):
diff -r e5cc81734221 -r f3ce7c7c0b58 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:54:30 2009 -0500
@@ -1,6 +1,7 @@
/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
#include "lib.h"
+#include "eacces-error.h"
#include "restrict-access.h"
#include "nfs-workarounds.h"
#include "mail-index-private.h"
@@ -14,6 +15,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
+#include <grp.h>
#ifdef HAVE_FLOCK
# include <sys/file.h>
@@ -260,7 +262,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) {
@@ -310,23 +312,42 @@ 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 =
+ eacces_error_get_creating("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) {
@@ -334,7 +355,33 @@ static int mbox_dotlock_privileged_op(st
"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 = eacces_error_get_creating("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
@@ -348,17 +395,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;
@@ -380,18 +426,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