dovecot-1.2: Improved "Permission denied" error handling. It'll ...

dovecot at dovecot.org dovecot at dovecot.org
Sat Dec 6 00:20:06 EET 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/1e42b631f037
changeset: 8518:1e42b631f037
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Dec 06 00:20:02 2008 +0200
description:
Improved "Permission denied" error handling. It'll now show also the uid/gid name.
Also moved the code to mail-error.c and used it when listing mailboxes.

diffstat:

10 files changed, 69 insertions(+), 48 deletions(-)
src/lib-storage/index/cydir/cydir-storage.c      |    6 +-
src/lib-storage/index/dbox/dbox-storage.c        |    8 +--
src/lib-storage/index/index-storage.c            |    2 
src/lib-storage/index/maildir/maildir-storage.c  |    6 +-
src/lib-storage/index/mbox/mbox-storage.c        |    6 +-
src/lib-storage/list/mailbox-list-maildir-iter.c |    5 +-
src/lib-storage/mail-error.c                     |   48 ++++++++++++++++++++++
src/lib-storage/mail-error.h                     |    3 +
src/lib-storage/mail-storage-private.h           |    2 
src/lib-storage/mail-storage.c                   |   31 --------------

diffs (273 lines):

diff -r 451e3cf38290 -r 1e42b631f037 src/lib-storage/index/cydir/cydir-storage.c
--- a/src/lib-storage/index/cydir/cydir-storage.c	Sat Dec 06 00:08:01 2008 +0200
+++ b/src/lib-storage/index/cydir/cydir-storage.c	Sat Dec 06 00:20:02 2008 +0200
@@ -94,7 +94,7 @@ static int cydir_create(struct mail_stor
 					"Root mail directory doesn't exist: %s",
 					list_set.root_dir);
 			} else if (errno == EACCES) {
-				*error_r = mail_storage_eacces_msg("stat",
+				*error_r = mail_error_eacces_msg("stat",
 							list_set.root_dir);
 			} else {
 				*error_r = t_strdup_printf(
@@ -106,7 +106,7 @@ 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_error_eacces_msg("mkdir", list_set.root_dir);
 		return -1;
 	} else {
 		*error_r = t_strdup_printf("mkdir(%s) failed: %m",
@@ -206,7 +206,7 @@ cydir_mailbox_open(struct mail_storage *
 			T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
 	} else if (errno == EACCES) {
 		mail_storage_set_critical(_storage, "%s",
-			mail_storage_eacces_msg("stat", path));
+			mail_error_eacces_msg("stat", path));
 	} else {
 		mail_storage_set_critical(_storage, "stat(%s) failed: %m",
 					  path);
diff -r 451e3cf38290 -r 1e42b631f037 src/lib-storage/index/dbox/dbox-storage.c
--- a/src/lib-storage/index/dbox/dbox-storage.c	Sat Dec 06 00:08:01 2008 +0200
+++ b/src/lib-storage/index/dbox/dbox-storage.c	Sat Dec 06 00:20:02 2008 +0200
@@ -107,7 +107,7 @@ static int dbox_create(struct mail_stora
 					"Root mail directory doesn't exist: %s",
 					list_set.root_dir);
 			} else if (errno == EACCES) {
-				*error_r = mail_storage_eacces_msg("stat",
+				*error_r = mail_error_eacces_msg("stat",
 							list_set.root_dir);
 			} else {
 				*error_r = t_strdup_printf(
@@ -120,8 +120,8 @@ static int dbox_create(struct mail_stora
 				 CREATE_MODE) == 0 || errno == EEXIST) {
 	} else if (errno == EACCES) {
 		if (_storage->ns->type != NAMESPACE_SHARED) {
-			*error_r = mail_storage_eacces_msg("mkdir",
-							   list_set.root_dir);
+			*error_r = mail_error_eacces_msg("mkdir",
+							 list_set.root_dir);
 			return -1;
 		}
 		/* can't create a new user, but we don't want to fail
@@ -308,7 +308,7 @@ dbox_mailbox_open(struct mail_storage *_
 			T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
 	} else if (errno == EACCES) {
 		mail_storage_set_critical(_storage, "%s",
-			mail_storage_eacces_msg("stat", path));
+			mail_error_eacces_msg("stat", path));
 	} else {
 		mail_storage_set_critical(_storage, "stat(%s) failed: %m",
 					  path);
diff -r 451e3cf38290 -r 1e42b631f037 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c	Sat Dec 06 00:08:01 2008 +0200
+++ b/src/lib-storage/index/index-storage.c	Sat Dec 06 00:20:02 2008 +0200
@@ -145,7 +145,7 @@ get_index_dir(struct mail_storage *stora
 		}
 		if (errno == EACCES) {
 			mail_storage_set_critical(storage, "%s",
-				mail_storage_eacces_msg("stat", index_dir));
+				mail_error_eacces_msg("stat", index_dir));
 			return NULL;
 		}
 
diff -r 451e3cf38290 -r 1e42b631f037 src/lib-storage/index/maildir/maildir-storage.c
--- a/src/lib-storage/index/maildir/maildir-storage.c	Sat Dec 06 00:08:01 2008 +0200
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Sat Dec 06 00:20:02 2008 +0200
@@ -211,8 +211,8 @@ maildir_create(struct mail_storage *_sto
 		if (stat(list_set.root_dir, &st) == 0) {
 			/* ok */
 		} else if (errno == EACCES) {
-			*error_r = mail_storage_eacces_msg("stat",
-							   list_set.root_dir);
+			*error_r = mail_error_eacces_msg("stat",
+							 list_set.root_dir);
 			return -1;
 		} else if (errno == ENOENT) {
 			*error_r = t_strdup_printf(
@@ -341,7 +341,7 @@ static int maildir_check_tmp(struct mail
 			return 0;
 		if (errno == EACCES) {
 			mail_storage_set_critical(storage, "%s",
-				mail_storage_eacces_msg("stat", path));
+				mail_error_eacces_msg("stat", path));
 			return -1;
 		}
 		mail_storage_set_critical(storage, "stat(%s) failed: %m", path);
diff -r 451e3cf38290 -r 1e42b631f037 src/lib-storage/index/mbox/mbox-storage.c
--- a/src/lib-storage/index/mbox/mbox-storage.c	Sat Dec 06 00:08:01 2008 +0200
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Sat Dec 06 00:20:02 2008 +0200
@@ -344,8 +344,8 @@ mbox_get_list_settings(struct mailbox_li
 		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);
+			*error_r = mail_error_eacces_msg("lstat",
+							 list_set->root_dir);
 			return -1;
 		} else if (errno != ENOENT && errno != ENOTDIR) {
 			*error_r = t_strdup_printf("lstat(%s) failed: %m",
@@ -502,7 +502,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_error_eacces_msg("open", inbox_path));
 		return -1;
 	} else if (errno != EEXIST) {
 		mail_storage_set_critical(storage,
diff -r 451e3cf38290 -r 1e42b631f037 src/lib-storage/list/mailbox-list-maildir-iter.c
--- a/src/lib-storage/list/mailbox-list-maildir-iter.c	Sat Dec 06 00:08:01 2008 +0200
+++ b/src/lib-storage/list/mailbox-list-maildir-iter.c	Sat Dec 06 00:20:02 2008 +0200
@@ -133,7 +133,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_error_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 451e3cf38290 -r 1e42b631f037 src/lib-storage/mail-error.c
--- a/src/lib-storage/mail-error.c	Sat Dec 06 00:08:01 2008 +0200
+++ b/src/lib-storage/mail-error.c	Sat Dec 06 00:20:02 2008 +0200
@@ -1,7 +1,13 @@
 /* Copyright (c) 2007-2008 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "str.h"
 #include "mail-error.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
 
 bool mail_error_from_errno(enum mail_error *error_r,
 			   const char **error_string_r)
@@ -21,3 +27,45 @@ bool mail_error_from_errno(enum mail_err
 	}
 	return TRUE;
 }
+
+const char *mail_error_eacces_msg(const char *func, const char *path)
+{
+	const char *prev_path = path, *dir = "/", *p;
+	const struct passwd *pw;
+	const struct group *group;
+	string_t *errmsg;
+	struct stat st;
+	int ret = -1;
+
+	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)
+			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);
+}
diff -r 451e3cf38290 -r 1e42b631f037 src/lib-storage/mail-error.h
--- a/src/lib-storage/mail-error.h	Sat Dec 06 00:08:01 2008 +0200
+++ b/src/lib-storage/mail-error.h	Sat Dec 06 00:20:02 2008 +0200
@@ -48,4 +48,7 @@ bool mail_error_from_errno(enum mail_err
 bool mail_error_from_errno(enum mail_error *error_r,
 			   const char **error_string_r);
 
+/* Build a helpful error message for a failed EACCESS syscall. */
+const char *mail_error_eacces_msg(const char *func, const char *path);
+
 #endif
diff -r 451e3cf38290 -r 1e42b631f037 src/lib-storage/mail-storage-private.h
--- a/src/lib-storage/mail-storage-private.h	Sat Dec 06 00:08:01 2008 +0200
+++ b/src/lib-storage/mail-storage-private.h	Sat Dec 06 00:20:02 2008 +0200
@@ -380,8 +380,6 @@ 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 451e3cf38290 -r 1e42b631f037 src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c	Sat Dec 06 00:08:01 2008 +0200
+++ b/src/lib-storage/mail-storage.c	Sat Dec 06 00:20:02 2008 +0200
@@ -3,7 +3,6 @@
 #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"
@@ -13,7 +12,6 @@
 #include "mailbox-search-result-private.h"
 
 #include <stdlib.h>
-#include <time.h>
 #include <ctype.h>
 
 #define DEFAULT_MAX_KEYWORD_LENGTH 50
@@ -931,32 +929,3 @@ 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