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