dovecot-1.1: Log better messages for "Permission denied" errors ...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jan 16 19:52:56 EET 2009


details:   http://hg.dovecot.org/dovecot-1.1/rev/108633554955
changeset: 8104:108633554955
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jan 16 12:52:45 2009 -0500
description:
Log better messages for "Permission denied" errors (backports from v1.2 tree).

diffstat:

7 files changed, 73 insertions(+), 14 deletions(-)
src/lib-storage/index/cydir/cydir-storage.c      |    3 
src/lib-storage/index/dbox/dbox-storage.c        |    3 
src/lib-storage/index/maildir/maildir-storage.c  |    3 
src/lib-storage/index/mbox/mbox-storage.c        |    2 
src/lib-storage/list/mailbox-list-maildir-iter.c |    6 +
src/lib-storage/mail-storage-private.h           |    1 
src/lib-storage/mail-storage.c                   |   69 ++++++++++++++++++----

diffs (186 lines):

diff -r 17c73b14ed9d -r 108633554955 src/lib-storage/index/cydir/cydir-storage.c
--- a/src/lib-storage/index/cydir/cydir-storage.c	Thu Jan 15 21:36:26 2009 -0500
+++ b/src/lib-storage/index/cydir/cydir-storage.c	Fri Jan 16 12:52:45 2009 -0500
@@ -105,7 +105,8 @@ static int cydir_create(struct mail_stor
 	} 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);
+		*error_r = mail_storage_create_eacces_msg("mkdir",
+							  list_set.root_dir);
 		return -1;
 	} else {
 		*error_r = t_strdup_printf("mkdir(%s) failed: %m",
diff -r 17c73b14ed9d -r 108633554955 src/lib-storage/index/dbox/dbox-storage.c
--- a/src/lib-storage/index/dbox/dbox-storage.c	Thu Jan 15 21:36:26 2009 -0500
+++ b/src/lib-storage/index/dbox/dbox-storage.c	Fri Jan 16 12:52:45 2009 -0500
@@ -122,7 +122,8 @@ static int dbox_create(struct mail_stora
 	} 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);
+		*error_r = mail_storage_create_eacces_msg("mkdir",
+							  list_set.root_dir);
 		return -1;
 	} else {
 		*error_r = t_strdup_printf("mkdir(%s) failed: %m",
diff -r 17c73b14ed9d -r 108633554955 src/lib-storage/index/maildir/maildir-storage.c
--- a/src/lib-storage/index/maildir/maildir-storage.c	Thu Jan 15 21:36:26 2009 -0500
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Fri Jan 16 12:52:45 2009 -0500
@@ -317,6 +317,9 @@ static int mkdir_verify(struct mail_stor
 	} else if (errno == ENOENT) {
 		mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND,
 			"Mailbox was deleted while it was being created");
+	} else if (errno == EACCES) {
+		mail_storage_set_critical(storage, "%s",
+			mail_storage_create_eacces_msg("mkdir", dir));
 	} else {
 		mail_storage_set_critical(storage,
 					  "mkdir(%s) failed: %m", dir);
diff -r 17c73b14ed9d -r 108633554955 src/lib-storage/index/mbox/mbox-storage.c
--- a/src/lib-storage/index/mbox/mbox-storage.c	Thu Jan 15 21:36:26 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Fri Jan 16 12:52:45 2009 -0500
@@ -495,7 +495,7 @@ static int verify_inbox(struct mail_stor
 		return -1;
 	} else if (errno == EACCES) {
 		mail_storage_set_critical(storage, "%s",
-			mail_storage_eacces_msg("open", inbox_path));
+			mail_storage_create_eacces_msg("open", inbox_path));
 		return -1;
 	} else if (errno != EEXIST) {
 		mail_storage_set_critical(storage,
diff -r 17c73b14ed9d -r 108633554955 src/lib-storage/list/mailbox-list-maildir-iter.c
--- a/src/lib-storage/list/mailbox-list-maildir-iter.c	Thu Jan 15 21:36:26 2009 -0500
+++ b/src/lib-storage/list/mailbox-list-maildir-iter.c	Fri Jan 16 12:52:45 2009 -0500
@@ -4,6 +4,7 @@
 #include "str.h"
 #include "home-expand.h"
 #include "imap-match.h"
+#include "mail-storage-private.h"
 #include "mailbox-tree.h"
 #include "mailbox-list-subscriptions.h"
 #include "mailbox-list-maildir.h"
@@ -134,7 +135,10 @@ maildir_fill_readdir(struct maildir_list
 
 	dirp = opendir(ctx->dir);
 	if (dirp == NULL) {
-		if (errno != ENOENT) {
+		if (errno == EACCES) {
+			mailbox_list_set_critical(ctx->ctx.list, "%s",
+				mail_storage_eacces_msg("opendir", ctx->dir));
+		} else if (errno != ENOENT) {
 			mailbox_list_set_critical(ctx->ctx.list,
 				"opendir(%s) failed: %m", ctx->dir);
 			return -1;
diff -r 17c73b14ed9d -r 108633554955 src/lib-storage/mail-storage-private.h
--- a/src/lib-storage/mail-storage-private.h	Thu Jan 15 21:36:26 2009 -0500
+++ b/src/lib-storage/mail-storage-private.h	Fri Jan 16 12:52:45 2009 -0500
@@ -329,6 +329,7 @@ void mailbox_set_deleted(struct mailbox 
 void mailbox_set_deleted(struct mailbox *box);
 
 const char *mail_storage_eacces_msg(const char *func, const char *path);
+const char *mail_storage_create_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 17c73b14ed9d -r 108633554955 src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c	Thu Jan 15 21:36:26 2009 -0500
+++ b/src/lib-storage/mail-storage.c	Fri Jan 16 12:52:45 2009 -0500
@@ -14,6 +14,8 @@
 #include <stdlib.h>
 #include <time.h>
 #include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
 
 /* Message to show to users when critical error occurs */
 #define CRITICAL_MSG \
@@ -773,31 +775,78 @@ void mailbox_set_deleted(struct mailbox 
 	box->mailbox_deleted = TRUE;
 }
 
-const char *mail_storage_eacces_msg(const char *func, const char *path)
+static const char *
+mail_storage_eacces_msg_full(const char *func, const char *path, bool creating)
 {
 	const char *prev_path = path, *dir = "/", *p;
-	string_t *errmsg = t_str_new(256);
+	const struct passwd *pw;
+	const struct group *group;
+	string_t *errmsg;
 	struct stat st;
 	int ret = -1;
 
-	str_printfa(errmsg, "%s(%s) failed: Permission denied (euid=%s egid=%s",
-		    func, path, dec2str(geteuid()), dec2str(getegid()));
+	errmsg = t_str_new(256);
+	str_printfa(errmsg, "%s(%s) failed: Permission denied (euid=%s",
+		    func, path, dec2str(geteuid()));
+
+	pw = getpwuid(geteuid());
+	if (pw != NULL)
+		str_printfa(errmsg, "(%s)", pw->pw_name);
+
+	str_printfa(errmsg, " egid=%s", dec2str(getegid()));
+	group = getgrgid(getegid());
+	if (group != NULL)
+		str_printfa(errmsg, "(%s)", group->gr_name);
+
 	while ((p = strrchr(prev_path, '/')) != NULL) {
 		dir = t_strdup_until(prev_path, p);
 		ret = stat(dir, &st);
-		if (ret == 0 || errno != EACCES)
+		if (ret == 0)
 			break;
+		if (errno == EACCES) {
+			/* see if we have access to parent directory */
+		} else if (errno == ENOENT && creating) {
+			/* probably mkdir_parents() failed here, find the first
+			   parent directory we couldn't create */
+		} else {
+			/* some other error, can't handle it */
+			str_printfa(errmsg, " stat(%s) failed: %m", dir);
+			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);
+		/* dir is the first parent directory we can stat() */
+		if (access(dir, X_OK) < 0) {
+			if (errno == EACCES)
+				str_printfa(errmsg, " missing +x perm: %s", dir);
+			else
+				str_printfa(errmsg, " access(%s, x) failed: %m", dir);
+		} else if (prev_path == path && access(path, R_OK) < 0) {
+			if (errno == EACCES)
+				str_printfa(errmsg, " missing +r perm: %s", path);
+			else
+				str_printfa(errmsg, " access(%s, r) failed: %m", path);
+		} else if (creating && access(dir, W_OK) < 0) {
+			if (errno == EACCES)
+				str_printfa(errmsg, " missing +w perm: %s", dir);
+			else
+				str_printfa(errmsg, " access(%s, w) failed: %m", dir);
+		} else
+			str_printfa(errmsg, " UNIX perms seem ok, ACL problem?");
 	}
 	str_append_c(errmsg, ')');
 	return str_c(errmsg);
 }
+
+const char *mail_storage_eacces_msg(const char *func, const char *path)
+{
+	return mail_storage_eacces_msg_full(func, path, FALSE);
+}
+
+const char *mail_storage_create_eacces_msg(const char *func, const char *path)
+{
+	return mail_storage_eacces_msg_full(func, path, TRUE);
+}


More information about the dovecot-cvs mailing list