annotate src/lib/eacces-error.c @ 8759:6ec819adfde3 HEAD

Moved user-friendly EACCES error message generation to lib/.
author Timo Sirainen <tss@iki.fi>
date Fri, 20 Feb 2009 17:35:49 -0500
parents
children e22e36a61fdd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8759
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1 /* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "str.h"
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "eacces-error.h"
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include <sys/stat.h>
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include <unistd.h>
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 #include <pwd.h>
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include <grp.h>
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 static const char *
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 eacces_error_get_full(const char *func, const char *path, bool creating)
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 const char *prev_path = path, *dir = "/", *p;
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 const struct passwd *pw;
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 const struct group *group;
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 string_t *errmsg;
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19 struct stat st;
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 int ret = -1;
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22 errmsg = t_str_new(256);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 str_printfa(errmsg, "%s(%s) failed: Permission denied (euid=%s",
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 func, path, dec2str(geteuid()));
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 pw = getpwuid(geteuid());
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 if (pw != NULL)
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 str_printfa(errmsg, "(%s)", pw->pw_name);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 str_printfa(errmsg, " egid=%s", dec2str(getegid()));
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 group = getgrgid(getegid());
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 if (group != NULL)
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 str_printfa(errmsg, "(%s)", group->gr_name);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 while ((p = strrchr(prev_path, '/')) != NULL) {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36 dir = t_strdup_until(prev_path, p);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 ret = stat(dir, &st);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 if (ret == 0)
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 break;
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 if (errno == EACCES) {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 /* see if we have access to parent directory */
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 } else if (errno == ENOENT && creating) {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 /* probably mkdir_parents() failed here, find the first
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44 parent directory we couldn't create */
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 } else {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46 /* some other error, can't handle it */
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 str_printfa(errmsg, " stat(%s) failed: %m", dir);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48 break;
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 }
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50 prev_path = dir;
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 dir = "/";
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 }
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 if (ret == 0) {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
55 /* dir is the first parent directory we can stat() */
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56 if (access(dir, X_OK) < 0) {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 if (errno == EACCES)
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58 str_printfa(errmsg, " missing +x perm: %s", dir);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59 else
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 str_printfa(errmsg, " access(%s, x) failed: %m", dir);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 } else if (creating && access(dir, W_OK) < 0) {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 if (errno == EACCES)
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 str_printfa(errmsg, " missing +w perm: %s", dir);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64 else
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 str_printfa(errmsg, " access(%s, w) failed: %m", dir);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 } else if (prev_path == path && access(path, R_OK) < 0) {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67 if (errno == EACCES)
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 str_printfa(errmsg, " missing +r perm: %s", path);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 else
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 str_printfa(errmsg, " access(%s, r) failed: %m", path);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71 } else
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 str_printfa(errmsg, " UNIX perms seem ok, ACL problem?");
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 }
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 str_append_c(errmsg, ')');
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75 return str_c(errmsg);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76 }
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 const char *eacces_error_get(const char *func, const char *path)
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
79 {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 return eacces_error_get_full(func, path, FALSE);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81 }
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 const char *eacces_error_get_creating(const char *func, const char *path)
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84 {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
85 return eacces_error_get_full(func, path, TRUE);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
86 }