From: Timo Sirainen Date: Fri, 16 Jan 2009 17:45:06 +0000 (-0500) Subject: Permission denied error handling can now suggest missing +w permissions. X-Git-Tag: 1.2.beta1~101 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7b85f7d35b2192bdff734d7d2891630bc30b2518;p=thirdparty%2Fdovecot%2Fcore.git Permission denied error handling can now suggest missing +w permissions. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/cydir/cydir-storage.c b/src/lib-storage/index/cydir/cydir-storage.c index e4e77afb8d..7af9bf98e8 100644 --- a/src/lib-storage/index/cydir/cydir-storage.c +++ b/src/lib-storage/index/cydir/cydir-storage.c @@ -106,7 +106,8 @@ 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_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 --git a/src/lib-storage/index/dbox/dbox-storage.c b/src/lib-storage/index/dbox/dbox-storage.c index 77a2e2f903..d29dfb72d1 100644 --- a/src/lib-storage/index/dbox/dbox-storage.c +++ b/src/lib-storage/index/dbox/dbox-storage.c @@ -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_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 --git a/src/lib-storage/index/maildir/maildir-storage.c b/src/lib-storage/index/maildir/maildir-storage.c index 5068bf2089..71ea3bc913 100644 --- a/src/lib-storage/index/maildir/maildir-storage.c +++ b/src/lib-storage/index/maildir/maildir-storage.c @@ -317,11 +317,15 @@ static int mkdir_verify(struct mail_storage *storage, } 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 --git a/src/lib-storage/index/mbox/mbox-storage.c b/src/lib-storage/index/mbox/mbox-storage.c index 3324061a7e..df24f2d129 100644 --- a/src/lib-storage/index/mbox/mbox-storage.c +++ b/src/lib-storage/index/mbox/mbox-storage.c @@ -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_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 --git a/src/lib-storage/mail-error.c b/src/lib-storage/mail-error.c index dd1b6faaba..92b21bd643 100644 --- a/src/lib-storage/mail-error.c +++ b/src/lib-storage/mail-error.c @@ -28,7 +28,8 @@ bool mail_error_from_errno(enum mail_error *error_r, 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 char *func, const char *path) 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 --git a/src/lib-storage/mail-error.h b/src/lib-storage/mail-error.h index 213cef3f12..dc00e87b4f 100644 --- a/src/lib-storage/mail-error.h +++ b/src/lib-storage/mail-error.h @@ -48,7 +48,10 @@ 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. */ +/* 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