dovecot: If mail storage or mailbox can't be accessed because of...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Jan 20 09:42:05 EET 2008
details: http://hg.dovecot.org/dovecot/rev/93fe72ef59f6
changeset: 7175:93fe72ef59f6
user: Timo Sirainen <tss at iki.fi>
date: Sun Jan 20 09:42:01 2008 +0200
description:
If mail storage or mailbox can't be accessed because of EACCES, log an error
message that clearly shows where the permission problem is.
diffstat:
8 files changed, 110 insertions(+), 41 deletions(-)
src/lib-storage/index/cydir/cydir-storage.c | 35 +++++++++++--------
src/lib-storage/index/dbox/dbox-storage.c | 42 ++++++++++++-----------
src/lib-storage/index/index-storage.c | 5 ++
src/lib-storage/index/maildir/maildir-save.c | 4 +-
src/lib-storage/index/maildir/maildir-storage.c | 23 +++++++++---
src/lib-storage/index/mbox/mbox-storage.c | 10 +++++
src/lib-storage/mail-storage-private.h | 2 +
src/lib-storage/mail-storage.c | 30 ++++++++++++++++
diffs (298 lines):
diff -r f090b6bf8021 -r 93fe72ef59f6 src/lib-storage/index/cydir/cydir-storage.c
--- a/src/lib-storage/index/cydir/cydir-storage.c Sun Jan 20 09:13:23 2008 +0200
+++ b/src/lib-storage/index/cydir/cydir-storage.c Sun Jan 20 09:42:01 2008 +0200
@@ -91,24 +91,29 @@ static int cydir_create(struct mail_stor
if ((_storage->flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
if (stat(list_set.root_dir, &st) < 0) {
- if (errno != ENOENT) {
+ if (errno == ENOENT) {
+ *error_r = t_strdup_printf(
+ "Root mail directory doesn't exist: %s",
+ list_set.root_dir);
+ } else if (errno == EACCES) {
+ *error_r = mail_storage_eacces_msg("stat",
+ list_set.root_dir);
+ } else {
*error_r = t_strdup_printf(
"stat(%s) failed: %m",
list_set.root_dir);
- } else {
- *error_r = t_strdup_printf(
- "Root mail directory doesn't exist: %s",
- list_set.root_dir);
}
return -1;
}
+ } else if (mkdir_parents(list_set.root_dir,
+ CREATE_MODE) == 0 || errno == EEXIST) {
+ } else if (errno == EACCES) {
+ *error_r = mail_storage_eacces_msg("mkdir", list_set.root_dir);
+ return -1;
} else {
- if (mkdir_parents(list_set.root_dir, CREATE_MODE) < 0 &&
- errno != EEXIST) {
- *error_r = t_strdup_printf("mkdir(%s) failed: %m",
- list_set.root_dir);
- return -1;
- }
+ *error_r = t_strdup_printf("mkdir(%s) failed: %m",
+ list_set.root_dir);
+ return -1;
}
if (mailbox_list_alloc(layout, &_storage->list, error_r) < 0)
@@ -196,12 +201,14 @@ cydir_mailbox_open(struct mail_storage *
}
mail_storage_set_error(_storage, MAIL_ERROR_NOTFOUND,
T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
- return NULL;
+ } else if (errno == EACCES) {
+ mail_storage_set_critical(_storage, "%s",
+ mail_storage_eacces_msg("stat", path));
} else {
mail_storage_set_critical(_storage, "stat(%s) failed: %m",
path);
- return NULL;
- }
+ }
+ return NULL;
}
static int cydir_mailbox_create(struct mail_storage *_storage,
diff -r f090b6bf8021 -r 93fe72ef59f6 src/lib-storage/index/dbox/dbox-storage.c
--- a/src/lib-storage/index/dbox/dbox-storage.c Sun Jan 20 09:13:23 2008 +0200
+++ b/src/lib-storage/index/dbox/dbox-storage.c Sun Jan 20 09:42:01 2008 +0200
@@ -95,24 +95,29 @@ static int dbox_create(struct mail_stora
if ((_storage->flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
if (stat(list_set.root_dir, &st) < 0) {
- if (errno != ENOENT) {
+ if (errno == ENOENT) {
+ *error_r = t_strdup_printf(
+ "Root mail directory doesn't exist: %s",
+ list_set.root_dir);
+ } else if (errno == EACCES) {
+ *error_r = mail_storage_eacces_msg("stat",
+ list_set.root_dir);
+ } else {
*error_r = t_strdup_printf(
"stat(%s) failed: %m",
list_set.root_dir);
- } else {
- *error_r = t_strdup_printf(
- "Root mail directory doesn't exist: %s",
- list_set.root_dir);
}
return -1;
}
+ } else if (mkdir_parents(list_set.root_dir,
+ CREATE_MODE) == 0 || errno == EEXIST) {
+ } else if (errno == EACCES) {
+ *error_r = mail_storage_eacces_msg("mkdir", list_set.root_dir);
+ return -1;
} else {
- if (mkdir_parents(list_set.root_dir, CREATE_MODE) < 0 &&
- errno != EEXIST) {
- *error_r = t_strdup_printf("mkdir(%s) failed: %m",
- list_set.root_dir);
- return -1;
- }
+ *error_r = t_strdup_printf("mkdir(%s) failed: %m",
+ list_set.root_dir);
+ return -1;
}
if (mailbox_list_alloc(layout, &_storage->list, error_r) < 0)
@@ -231,13 +236,8 @@ dbox_cleanup_if_exists(struct mail_stora
{
struct stat st;
- if (stat(path, &st) < 0) {
- if (errno != ENOENT) {
- mail_storage_set_critical(storage,
- "stat(%s) failed: %m", path);
- }
+ if (stat(path, &st) < 0)
return FALSE;
- }
/* check once in a while if there are temp files to clean up */
if (st.st_atime > st.st_ctime + DBOX_TMP_DELETE_SECS) {
@@ -281,12 +281,14 @@ dbox_mailbox_open(struct mail_storage *_
mail_storage_set_error(_storage, MAIL_ERROR_NOTFOUND,
T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
- return NULL;
+ } else if (errno == EACCES) {
+ mail_storage_set_critical(_storage, "%s",
+ mail_storage_eacces_msg("stat", path));
} else {
mail_storage_set_critical(_storage, "stat(%s) failed: %m",
path);
- return NULL;
- }
+ }
+ return NULL;
}
static int dbox_storage_mailbox_close(struct mailbox *box)
diff -r f090b6bf8021 -r 93fe72ef59f6 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c Sun Jan 20 09:13:23 2008 +0200
+++ b/src/lib-storage/index/index-storage.c Sun Jan 20 09:42:01 2008 +0200
@@ -108,6 +108,11 @@ get_index_dir(struct mail_storage *stora
return NULL;
if (stat(index_dir, st_r) == 0)
return index_dir;
+ }
+ if (errno == EACCES) {
+ mail_storage_set_critical(storage, "%s",
+ mail_storage_eacces_msg("stat", index_dir));
+ return NULL;
}
mail_storage_set_critical(storage, "stat(%s) failed: %m",
diff -r f090b6bf8021 -r 93fe72ef59f6 src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c Sun Jan 20 09:13:23 2008 +0200
+++ b/src/lib-storage/index/maildir/maildir-save.c Sun Jan 20 09:42:01 2008 +0200
@@ -220,11 +220,11 @@ maildir_get_updated_filename(struct mail
MAILDIR_EXTRA_FILE_SIZE, mf->size);
}
- if (mf->vsize != (uoff_t)-1) {
+ /*if (mf->vsize != (uoff_t)-1) {
basename = t_strdup_printf("%s,%c=%"PRIuUOFF_T, basename,
MAILDIR_EXTRA_VIRTUAL_SIZE,
mf->vsize);
- }
+ }*/
if (mf->keywords_count == 0) {
if ((mf->flags & MAIL_FLAGS_MASK) == MAIL_RECENT) {
diff -r f090b6bf8021 -r 93fe72ef59f6 src/lib-storage/index/maildir/maildir-storage.c
--- a/src/lib-storage/index/maildir/maildir-storage.c Sun Jan 20 09:13:23 2008 +0200
+++ b/src/lib-storage/index/maildir/maildir-storage.c Sun Jan 20 09:42:01 2008 +0200
@@ -206,12 +206,20 @@ maildir_create(struct mail_storage *_sto
}
if ((flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
- if (stat(list_set.root_dir, &st) < 0) {
- if (errno != ENOENT) {
- i_error("stat(%s) failed: %m",
+ if (stat(list_set.root_dir, &st) == 0) {
+ /* ok */
+ } else if (errno == EACCES) {
+ *error_r = mail_storage_eacces_msg("stat",
+ list_set.root_dir);
+ return -1;
+ } else if (errno == ENOENT) {
+ *error_r = t_strdup_printf(
+ "Root mail directory doesn't exist: %s",
list_set.root_dir);
- }
- *error_r = "Mail storage doesn't exist";
+ return -1;
+ } else {
+ *error_r = t_strdup_printf("stat(%s) failed: %m",
+ list_set.root_dir);
return -1;
}
}
@@ -324,6 +332,11 @@ static int maildir_check_tmp(struct mail
if (stat(path, &st) < 0) {
if (errno == ENOENT)
return 0;
+ if (errno == EACCES) {
+ mail_storage_set_critical(storage, "%s",
+ mail_storage_eacces_msg("stat", path));
+ return -1;
+ }
mail_storage_set_critical(storage, "stat(%s) failed: %m", path);
return -1;
}
diff -r f090b6bf8021 -r 93fe72ef59f6 src/lib-storage/index/mbox/mbox-storage.c
--- a/src/lib-storage/index/mbox/mbox-storage.c Sun Jan 20 09:13:23 2008 +0200
+++ b/src/lib-storage/index/mbox/mbox-storage.c Sun Jan 20 09:42:01 2008 +0200
@@ -335,6 +335,10 @@ mbox_get_list_settings(struct mailbox_li
/* make sure the directory exists */
if (lstat(list_set->root_dir, &st) == 0) {
/* yep, go ahead */
+ } else if (errno == EACCES) {
+ *error_r = mail_storage_eacces_msg("lstat",
+ list_set->root_dir);
+ return -1;
} else if (errno != ENOENT && errno != ENOTDIR) {
*error_r = t_strdup_printf("lstat(%s) failed: %m",
list_set->root_dir);
@@ -446,9 +450,15 @@ static int verify_inbox(struct mail_stor
"mbox root directory can't be a file: %s "
"(http://wiki.dovecot.org/MailLocation/Mbox)",
rootdir);
+ return -1;
+ } else if (errno == EACCES) {
+ mail_storage_set_critical(storage, "%s",
+ mail_storage_eacces_msg("open", inbox_path));
+ return -1;
} else if (errno != EEXIST) {
mail_storage_set_critical(storage,
"open(%s, O_CREAT) failed: %m", inbox_path);
+ return -1;
}
return 0;
diff -r f090b6bf8021 -r 93fe72ef59f6 src/lib-storage/mail-storage-private.h
--- a/src/lib-storage/mail-storage-private.h Sun Jan 20 09:13:23 2008 +0200
+++ b/src/lib-storage/mail-storage-private.h Sun Jan 20 09:42:01 2008 +0200
@@ -322,6 +322,8 @@ void mail_set_expunged(struct mail *mail
void mail_set_expunged(struct mail *mail);
void mailbox_set_deleted(struct mailbox *box);
+const char *mail_storage_eacces_msg(const char *func, const char *path);
+
enum mailbox_list_flags
mail_storage_get_list_flags(enum mail_storage_flags storage_flags);
diff -r f090b6bf8021 -r 93fe72ef59f6 src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c Sun Jan 20 09:13:23 2008 +0200
+++ b/src/lib-storage/mail-storage.c Sun Jan 20 09:42:01 2008 +0200
@@ -3,6 +3,7 @@
#include "lib.h"
#include "ioloop.h"
#include "array.h"
+#include "str.h"
#include "var-expand.h"
#include "mail-index-private.h"
#include "mailbox-list-private.h"
@@ -751,3 +752,32 @@ void mailbox_set_deleted(struct mailbox
"Mailbox was deleted under us");
box->mailbox_deleted = TRUE;
}
+
+const char *mail_storage_eacces_msg(const char *func, const char *path)
+{
+ const char *prev_path = path, *dir = "/", *p;
+ string_t *errmsg = t_str_new(256);
+ struct stat st;
+ int ret = -1;
+
+ str_printfa(errmsg, "%s(%s) failed: Permission denied (euid=%s egid=%s",
+ func, path, dec2str(geteuid()), dec2str(getegid()));
+ while ((p = strrchr(prev_path, '/')) != NULL) {
+ dir = t_strdup_until(prev_path, p);
+ ret = stat(dir, &st);
+ if (ret == 0 || errno != EACCES)
+ break;
+ prev_path = dir;
+ dir = "/";
+ }
+
+ if (ret == 0) {
+ if (access(dir, X_OK) < 0 && errno == EACCES)
+ str_printfa(errmsg, " missing +x perm: %s", dir);
+ else if (prev_path == path &&
+ access(path, R_OK) < 0 && errno == EACCES)
+ str_printfa(errmsg, " missing +r perm: %s", path);
+ }
+ str_append_c(errmsg, ')');
+ return str_c(errmsg);
+}
More information about the dovecot-cvs
mailing list