]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Improved "Permission denied" error handling. It'll now show also the uid/gid name.
authorTimo Sirainen <tss@iki.fi>
Fri, 5 Dec 2008 22:20:02 +0000 (00:20 +0200)
committerTimo Sirainen <tss@iki.fi>
Fri, 5 Dec 2008 22:20:02 +0000 (00:20 +0200)
Also moved the code to mail-error.c and used it when listing mailboxes.

--HG--
branch : HEAD

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-storage.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/list/mailbox-list-maildir-iter.c
src/lib-storage/mail-error.c
src/lib-storage/mail-error.h
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c

index 682a0d90e5b529616e95dc05d2766ef0d6932bbf..651480fda9334f3325a8916402b923d420eda6b0 100644 (file)
@@ -94,7 +94,7 @@ static int cydir_create(struct mail_storage *_storage, const char *data,
                                        "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_storage *_storage, const char *data,
        } 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 *_storage, const char *name,
                        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);
index 132b4503a8704f00325f3a6f25e4235084a2d042..7fc4585cfc619751b5e8fdf4292e6f020069ba91 100644 (file)
@@ -107,7 +107,7 @@ static int dbox_create(struct mail_storage *_storage, const char *data,
                                        "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_storage *_storage, const char *data,
                                 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 *_storage, const char *name,
                        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);
index a2127bf32e00e5414e52b3e80592e71d9057bc79..e9a6c2e5b13891b0851c51879efddf982371aa52 100644 (file)
@@ -145,7 +145,7 @@ get_index_dir(struct mail_storage *storage, const char *name,
                }
                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;
                }
 
index 224f4d4686669f79cfbfdf6d71987c8c84c0a249..aeb500f90625cdf554bf8923fde2d7d276756f44 100644 (file)
@@ -211,8 +211,8 @@ maildir_create(struct mail_storage *_storage, const char *data,
                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_storage *storage, const char *dir)
                        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);
index 0f5ed87fa143f5388d98b78e568c536a3274e15d..d5e2b7f752799e34dcb3bd87190a28b70950e475 100644 (file)
@@ -344,8 +344,8 @@ mbox_get_list_settings(struct mailbox_list_settings *list_set,
                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_storage *storage)
                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,
index 8273e37277e38fbb5b4bcd7280ae432566a1a307..c76e2a9a2c2c580038e42c5a45c26e4eb9c688d4 100644 (file)
@@ -133,7 +133,10 @@ maildir_fill_readdir(struct maildir_list_iterate_context *ctx,
 
        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;
index 3c40be7e5fd0805d9102163dacf808bff730ea94..13df51981621189263847b984d85fc1952fe43e3 100644 (file)
@@ -1,8 +1,14 @@
 /* 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_error *error_r,
        }
        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);
+}
index 0a65febe8b06094501980ffa5ea4a9da1fceb0cd..213cef3f12bac50bf8d4137491535bc02e5819f6 100644 (file)
@@ -48,4 +48,7 @@ enum mail_error {
 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
index 3b41fa8e125b7901b60d526ff49c45dbe84517ae..2f56a6b7534aecced920bc736edc20a6a2031dba 100644 (file)
@@ -380,8 +380,6 @@ const char *mail_generate_guid_string(void);
 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);
 
index 6dbff9c1e6643a5704a9b1d98a71d025a9fc9f65..b2e2f3774b8ff88843ea3dbcf05961783a81977d 100644 (file)
@@ -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 *box)
                               "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);
-}