dovecot-1.2: Permission denied error handling can now suggest mi...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jan 16 21:21:33 EET 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/dd53d40a2f09
changeset: 8642:dd53d40a2f09
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jan 16 12:45:06 2009 -0500
description:
Permission denied error handling can now suggest missing +w permissions.

diffstat:

6 files changed, 58 insertions(+), 18 deletions(-)
src/lib-storage/index/cydir/cydir-storage.c     |    3 -
src/lib-storage/index/dbox/dbox-storage.c       |    4 -
src/lib-storage/index/maildir/maildir-storage.c |   14 ++++--
src/lib-storage/index/mbox/mbox-storage.c       |    2 
src/lib-storage/mail-error.c                    |   48 +++++++++++++++++++----
src/lib-storage/mail-error.h                    |    5 +-

diffs (151 lines):

diff -r 02ba04b6aa07 -r dd53d40a2f09 src/lib-storage/index/cydir/cydir-storage.c
--- a/src/lib-storage/index/cydir/cydir-storage.c	Fri Jan 16 12:29:30 2009 -0500
+++ b/src/lib-storage/index/cydir/cydir-storage.c	Fri Jan 16 12:45:06 2009 -0500
@@ -106,7 +106,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_error_eacces_msg("mkdir", list_set.root_dir);
+		*error_r = mail_error_create_eacces_msg("mkdir",
+							list_set.root_dir);
 		return -1;
 	} else {
 		*error_r = t_strdup_printf("mkdir(%s) failed: %m",
diff -r 02ba04b6aa07 -r dd53d40a2f09 src/lib-storage/index/dbox/dbox-storage.c
--- a/src/lib-storage/index/dbox/dbox-storage.c	Fri Jan 16 12:29:30 2009 -0500
+++ b/src/lib-storage/index/dbox/dbox-storage.c	Fri Jan 16 12:45:06 2009 -0500
@@ -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_error_eacces_msg("mkdir",
-							 list_set.root_dir);
+			*error_r = mail_error_create_eacces_msg("mkdir",
+							list_set.root_dir);
 			return -1;
 		}
 		/* can't create a new user, but we don't want to fail
diff -r 02ba04b6aa07 -r dd53d40a2f09 src/lib-storage/index/maildir/maildir-storage.c
--- a/src/lib-storage/index/maildir/maildir-storage.c	Fri Jan 16 12:29:30 2009 -0500
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Fri Jan 16 12:45:06 2009 -0500
@@ -317,11 +317,15 @@ 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 && storage->ns->type == NAMESPACE_SHARED) {
-		/* shared namespace, don't log permission errors */
-		mail_storage_set_error(storage, MAIL_ERROR_PERM,
-				       MAIL_ERRSTR_NO_PERMISSION);
-		return -1;
+	} else if (errno == EACCES) {
+		if (storage->ns->type == NAMESPACE_SHARED) {
+			/* shared namespace, don't log permission errors */
+			mail_storage_set_error(storage, MAIL_ERROR_PERM,
+					       MAIL_ERRSTR_NO_PERMISSION);
+			return -1;
+		}
+		mail_storage_set_critical(storage, "%s",
+			mail_error_create_eacces_msg("mkdir", dir));
 	} else {
 		mail_storage_set_critical(storage,
 					  "mkdir(%s) failed: %m", dir);
diff -r 02ba04b6aa07 -r dd53d40a2f09 src/lib-storage/index/mbox/mbox-storage.c
--- a/src/lib-storage/index/mbox/mbox-storage.c	Fri Jan 16 12:29:30 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Fri Jan 16 12:45:06 2009 -0500
@@ -502,7 +502,7 @@ static int verify_inbox(struct mail_stor
 		return -1;
 	} else if (errno == EACCES) {
 		mail_storage_set_critical(storage, "%s",
-			mail_error_eacces_msg("open", inbox_path));
+			mail_error_create_eacces_msg("open", inbox_path));
 		return -1;
 	} else if (errno != EEXIST) {
 		mail_storage_set_critical(storage,
diff -r 02ba04b6aa07 -r dd53d40a2f09 src/lib-storage/mail-error.c
--- a/src/lib-storage/mail-error.c	Fri Jan 16 12:29:30 2009 -0500
+++ b/src/lib-storage/mail-error.c	Fri Jan 16 12:45:06 2009 -0500
@@ -28,7 +28,8 @@ bool mail_error_from_errno(enum mail_err
 	return TRUE;
 }
 
-const char *mail_error_eacces_msg(const char *func, const char *path)
+static const char *
+mail_error_eacces_msg_full(const char *func, const char *path, bool creating)
 {
 	const char *prev_path = path, *dir = "/", *p;
 	const struct passwd *pw;
@@ -53,21 +54,52 @@ const char *mail_error_eacces_msg(const 
 	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);
-		else
+		/* 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_error_eacces_msg(const char *func, const char *path)
+{
+	return mail_error_eacces_msg_full(func, path, FALSE);
+}
+
+const char *mail_error_create_eacces_msg(const char *func, const char *path)
+{
+	return mail_error_eacces_msg_full(func, path, TRUE);
+}
diff -r 02ba04b6aa07 -r dd53d40a2f09 src/lib-storage/mail-error.h
--- a/src/lib-storage/mail-error.h	Fri Jan 16 12:29:30 2009 -0500
+++ b/src/lib-storage/mail-error.h	Fri Jan 16 12:45:06 2009 -0500
@@ -48,7 +48,10 @@ 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. */
+/* Build a helpful error message for a failed EACCES syscall. */
 const char *mail_error_eacces_msg(const char *func, const char *path);
+/* Build a helpful error message for a failed EACCES syscall that tried to
+   write to directory (create, rename, etc). */
+const char *mail_error_create_eacces_msg(const char *func, const char *path);
 
 #endif


More information about the dovecot-cvs mailing list