# HG changeset patch # User Timo Sirainen # Date 1228515602 -7200 # Node ID 1e42b631f0370a6a0e1e237ea43e6319916319ba # Parent 451e3cf38290e55abeb3632d5b48bfec39e3980f 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. 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 @@ "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 @@ } 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 @@ 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 @@ "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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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,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 +#include +#include +#include + bool mail_error_from_errno(enum mail_error *error_r, const char **error_string_r) { @@ -21,3 +27,45 @@ } 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_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 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 -#include #include #define DEFAULT_MAX_KEYWORD_LENGTH 50 @@ -931,32 +929,3 @@ "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); -}