eacces-error.c revision 0471a9dde7b4fb55779261460c973f85088b4b0c
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen unsigned int i, count;
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen for (i = 0; i < count; i++) {
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainenstatic int test_access(const char *path, int mode, string_t *errmsg)
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen str_printfa(errmsg, " access(%s, %d) failed: %m",
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen /* access() uses real uid, not effective uid.
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen we'll have to do these checks manually. */
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen if (stat(t_strconcat(path, "/test", NULL), &st) == 0)
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen str_printfa(errmsg, " stat(%s/test) failed: %m", path);
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen str_printfa(errmsg, " stat(%s) failed: %m", path);
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainenstatic const char *
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Siraineneacces_error_get_full(const char *func, const char *path, bool creating)
0471a9dde7b4fb55779261460c973f85088b4b0cTimo Sirainen /* we have no path. do the file access checks anyway. */
761c440316cc003817b3375b627287eceb6f6dceTimo Sirainen str_printfa(errmsg, " failed: Permission denied (euid=%s",
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen str_printfa(errmsg, " egid=%s", dec2str(getegid()));
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen while ((p = strrchr(prev_path, '/')) != NULL) {
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen /* see if we have access to parent directory */
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen /* probably mkdir_parents() failed here, find the first
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen parent directory we couldn't create */
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen /* some other error, can't handle it */
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen str_printfa(errmsg, " stat(%s) failed: %m", dir);
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen /* dir is the first parent directory we can stat() */
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen str_printfa(errmsg, " missing +x perm: %s", dir);
5e9a39da0a9aba60b50e2c1d401f102703431b73Timo Sirainen } else if (creating && test_access(dir, W_OK, errmsg) < 0) {
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen str_printfa(errmsg, " missing +w perm: %s", dir);
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen str_printfa(errmsg, " missing +r perm: %s", path);
826d9b7a1dec011e4777b334af5f4dc4feebb64bTimo Sirainen } else if (!creating && test_access(path, W_OK, errmsg) < 0) {
826d9b7a1dec011e4777b334af5f4dc4feebb64bTimo Sirainen /* this produces a wrong error if the operation didn't
826d9b7a1dec011e4777b334af5f4dc4feebb64bTimo Sirainen actually need write permissions, but we don't know
826d9b7a1dec011e4777b334af5f4dc4feebb64bTimo Sirainen str_printfa(errmsg, " missing +w perm: %s", path);
75804457bc8837885b3b6200e7fd680264872014Timo Sirainen "some security policy wrong?");
49dc101839b5f37a1a3c000421796f162e0017d9Timo Sirainen str_printfa(errmsg, ", conflicting dir uid=%s(%s)",
49dc101839b5f37a1a3c000421796f162e0017d9Timo Sirainen str_append(errmsg, ", euid is not dir owner");
7ca397e910d2b267bcfaecbcdf9b23523c639776Timo Sirainen if (gr_name != NULL && dir_st.st_gid != getegid()) {
7ca397e910d2b267bcfaecbcdf9b23523c639776Timo Sirainen if (group != NULL && strcmp(group->gr_name, gr_name) == 0) {
49dc101839b5f37a1a3c000421796f162e0017d9Timo Sirainen str_printfa(errmsg, ", conflicting dir gid=%s(%s)",
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainenconst char *eacces_error_get(const char *func, const char *path)
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen return eacces_error_get_full(func, path, FALSE);
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainenconst char *eacces_error_get_creating(const char *func, const char *path)
5cdd1691e5185ecfe424f5de7b6f697813b88ba2Timo Sirainen return eacces_error_get_full(func, path, TRUE);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainenconst char *eperm_error_get_chgrp(const char *func, const char *path,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen str_printfa(errmsg, "%s(%s, -1, %s", func, path, dec2str(gid));
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen str_printfa(errmsg, ") failed: Operation not permitted (egid=%s",
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen str_printfa(errmsg, ", group based on %s", gid_origin);