Mercurial > dovecot > core-2.2
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 |
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 } |