From: Timo Sirainen Date: Fri, 20 Feb 2009 22:35:49 +0000 (-0500) Subject: Moved user-friendly EACCES error message generation to lib/. X-Git-Tag: 1.2.beta2~72 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5cdd1691e5185ecfe424f5de7b6f697813b88ba2;p=thirdparty%2Fdovecot%2Fcore.git Moved user-friendly EACCES error message generation to lib/. --HG-- branch : HEAD --- diff --git a/src/lib-storage/mail-error.c b/src/lib-storage/mail-error.c index e1a79d65a5..0a1afd92d7 100644 --- a/src/lib-storage/mail-error.c +++ b/src/lib-storage/mail-error.c @@ -1,14 +1,9 @@ /* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */ #include "lib.h" -#include "str.h" +#include "eacces-error.h" #include "mail-error.h" -#include -#include -#include -#include - bool mail_error_from_errno(enum mail_error *error_r, const char **error_string_r) { @@ -28,78 +23,12 @@ bool mail_error_from_errno(enum mail_error *error_r, return TRUE; } -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; - 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) - 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) { - /* 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 (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 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 - 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); + return eacces_error_get(func, path); } const char *mail_error_create_eacces_msg(const char *func, const char *path) { - return mail_error_eacces_msg_full(func, path, TRUE); + return eacces_error_get_creating(func, path); } diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 1a8b4abdf0..8adf75cfb3 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -20,6 +20,7 @@ liblib_a_SOURCES = \ compat.c \ crc32.c \ data-stack.c \ + eacces-error.c \ env-util.c \ failures.c \ fd-close-on-exec.c \ @@ -121,6 +122,7 @@ headers = \ compat.h \ crc32.h \ data-stack.h \ + eacces-error.h \ env-util.h \ failures.h \ fd-close-on-exec.h \ diff --git a/src/lib/eacces-error.c b/src/lib/eacces-error.c new file mode 100644 index 0000000000..94644ac269 --- /dev/null +++ b/src/lib/eacces-error.c @@ -0,0 +1,86 @@ +/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "eacces-error.h" + +#include +#include +#include +#include + +static const char * +eacces_error_get_full(const char *func, const char *path, bool creating) +{ + 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) + 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) { + /* 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 (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 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 + str_printfa(errmsg, " UNIX perms seem ok, ACL problem?"); + } + str_append_c(errmsg, ')'); + return str_c(errmsg); +} + +const char *eacces_error_get(const char *func, const char *path) +{ + return eacces_error_get_full(func, path, FALSE); +} + +const char *eacces_error_get_creating(const char *func, const char *path) +{ + return eacces_error_get_full(func, path, TRUE); +} diff --git a/src/lib/eacces-error.h b/src/lib/eacces-error.h new file mode 100644 index 0000000000..20d9169ea5 --- /dev/null +++ b/src/lib/eacces-error.h @@ -0,0 +1,8 @@ +#ifndef EACCES_ERROR_H +#define EACCES_ERROR_H + +/* Return a user-friendly error message for EACCES failures. */ +const char *eacces_error_get(const char *func, const char *path); +const char *eacces_error_get_creating(const char *func, const char *path); + +#endif