Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7175:93fe72ef59f6 HEAD
If mail storage or mailbox can't be accessed because of EACCES, log an error
message that clearly shows where the permission problem is.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 20 Jan 2008 09:42:01 +0200 |
parents | f090b6bf8021 |
children | d719b373a1aa |
files | src/lib-storage/index/cydir/cydir-storage.c src/lib-storage/index/dbox/dbox-storage.c src/lib-storage/index/index-storage.c src/lib-storage/index/maildir/maildir-save.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c |
diffstat | 8 files changed, 108 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ if ((_storage->flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) { if (stat(list_set.root_dir, &st) < 0) { - if (errno != ENOENT) { - *error_r = t_strdup_printf( - "stat(%s) failed: %m", - list_set.root_dir); - } else { + 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); } 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 @@ } 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,
--- 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 @@ if ((_storage->flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) { if (stat(list_set.root_dir, &st) < 0) { - if (errno != ENOENT) { - *error_r = t_strdup_printf( - "stat(%s) failed: %m", - list_set.root_dir); - } else { + 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); } 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 @@ { 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 @@ 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)
--- 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 @@ -109,6 +109,11 @@ 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", index_dir);
--- 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_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) {
--- 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 @@ } 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 @@ 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; }
--- 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 @@ /* 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 @@ "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;
--- 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 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);
--- 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 @@ "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); +}