Mercurial > dovecot > core-2.2
annotate src/lib/eacces-error.c @ 13674:439ba86c91fc
eacces_error_get*(): Crashfix for recent change.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 08 Nov 2011 22:49:57 +0200 |
parents | b6e5cf112b3e |
children | 8714ccb35848 |
rev | line source |
---|---|
12782
447bce266022
Updated copyright notices to include year 2011.
Timo Sirainen <tss@iki.fi>
parents:
12050
diff
changeset
|
1 /* Copyright (c) 2007-2011 Dovecot authors, see the included COPYING file */ |
8759
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" |
10502
13be6ac759ee
Added t_get_current_dir() and use it instead of getcwd().
Timo Sirainen <tss@iki.fi>
parents:
10210
diff
changeset
|
5 #include "abspath.h" |
12859
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
6 #include "ipwd.h" |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
7 #include "restrict-access.h" |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #include "eacces-error.h" |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 #include <sys/stat.h> |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 #include <unistd.h> |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
13 static bool is_in_group(gid_t gid) |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
14 { |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
15 const gid_t *gids; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
16 unsigned int i, count; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
17 |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
18 if (getegid() == gid) |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
19 return TRUE; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
20 |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
21 gids = restrict_get_groups_list(&count); |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
22 for (i = 0; i < count; i++) { |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
23 if (gids[i] == gid) |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
24 return TRUE; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
25 } |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
26 return FALSE; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
27 } |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
28 |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
29 static void write_eacces_error(string_t *errmsg, const char *path, int mode) |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
30 { |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
31 char c; |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
32 |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
33 switch (mode) { |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
34 case R_OK: |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
35 c = 'r'; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
36 break; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
37 case W_OK: |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
38 c = 'w'; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
39 break; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
40 case X_OK: |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
41 c = 'x'; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
42 break; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
43 default: |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
44 i_unreached(); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
45 } |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
46 str_printfa(errmsg, " missing +%c perm: %s", c, path); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
47 } |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
48 |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
49 static int |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
50 test_manual_access(const char *path, int access_mode, bool write_eacces, |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
51 string_t *errmsg) |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
52 { |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
53 const struct group *group; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
54 bool user_not_in_group = FALSE; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
55 struct stat st; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
56 int mode; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
57 |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
58 if (stat(path, &st) < 0) { |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
59 str_printfa(errmsg, " stat(%s) failed: %m", path); |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
60 return -1; |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
61 } |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
62 |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
63 switch (access_mode) { |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
64 case R_OK: |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
65 mode = 04; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
66 break; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
67 case W_OK: |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
68 mode = 02; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
69 break; |
13674
439ba86c91fc
eacces_error_get*(): Crashfix for recent change.
Timo Sirainen <tss@iki.fi>
parents:
13645
diff
changeset
|
70 case X_OK: |
439ba86c91fc
eacces_error_get*(): Crashfix for recent change.
Timo Sirainen <tss@iki.fi>
parents:
13645
diff
changeset
|
71 mode = 01; |
439ba86c91fc
eacces_error_get*(): Crashfix for recent change.
Timo Sirainen <tss@iki.fi>
parents:
13645
diff
changeset
|
72 break; |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
73 default: |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
74 i_unreached(); |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
75 } |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
76 |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
77 if (st.st_uid == geteuid()) |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
78 st.st_mode = (st.st_mode & 0700) >> 6; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
79 else if (is_in_group(st.st_gid)) |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
80 st.st_mode = (st.st_mode & 0070) >> 3; |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
81 else { |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
82 if ((((st.st_mode & 0070) >> 3) & mode) != 0) |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
83 user_not_in_group = TRUE; |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
84 st.st_mode = (st.st_mode & 0007); |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
85 } |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
86 |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
87 if ((st.st_mode & mode) != 0) |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
88 return 0; |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
89 |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
90 if (write_eacces) |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
91 write_eacces_error(errmsg, path, access_mode); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
92 if (user_not_in_group) { |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
93 /* group would have had enough permissions, |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
94 but we don't belong to the group */ |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
95 str_printfa(errmsg, ", we're not in group %s", |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
96 dec2str(st.st_gid)); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
97 group = getgrgid(st.st_gid); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
98 if (group != NULL) |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
99 str_printfa(errmsg, "(%s)", group->gr_name); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
100 } |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
101 errno = EACCES; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
102 return -1; |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
103 } |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
104 |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
105 static int test_access(const char *path, int access_mode, string_t *errmsg) |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
106 { |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
107 struct stat st; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
108 |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
109 if (getuid() == geteuid()) { |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
110 if (access(path, access_mode) == 0) |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
111 return 0; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
112 |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
113 if (errno == EACCES) { |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
114 write_eacces_error(errmsg, path, access_mode); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
115 (void)test_manual_access(path, access_mode, |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
116 FALSE, errmsg); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
117 errno = EACCES; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
118 } else { |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
119 str_printfa(errmsg, " access(%s, %d) failed: %m", |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
120 path, access_mode); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
121 } |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
122 return -1; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
123 } |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
124 |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
125 /* access() uses real uid, not effective uid. |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
126 we'll have to do these checks manually. */ |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
127 switch (access_mode) { |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
128 case X_OK: |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
129 if (stat(t_strconcat(path, "/test", NULL), &st) == 0) |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
130 return 0; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
131 if (errno == ENOENT || errno == ENOTDIR) |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
132 return 0; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
133 if (errno == EACCES) |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
134 write_eacces_error(errmsg, path, access_mode); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
135 else |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
136 str_printfa(errmsg, " stat(%s/test) failed: %m", path); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
137 return -1; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
138 case R_OK: |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
139 case W_OK: |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
140 break; |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
141 default: |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
142 i_unreached(); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
143 } |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
144 |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
145 return test_manual_access(path, access_mode, TRUE, errmsg); |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
146 } |
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
147 |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
148 static const char * |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
149 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
|
150 { |
13057
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
151 const char *prev_path, *dir = NULL, *p; |
10553
b8966b8133f2
eacces_error_get*(): Check and warn if multiple uids/gids have same name.
Timo Sirainen <tss@iki.fi>
parents:
10502
diff
changeset
|
152 const char *pw_name = NULL, *gr_name = NULL; |
12859
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
153 struct passwd pw; |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
154 struct group group; |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
155 string_t *errmsg; |
13057
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
156 struct stat st; |
13059
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
157 int orig_errno, ret, missing_mode = 0; |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
158 |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
159 orig_errno = errno; |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
160 errmsg = t_str_new(256); |
9589
f564209e9396
eacces_error_get*(): Show current directory if path is relative.
Timo Sirainen <tss@iki.fi>
parents:
9537
diff
changeset
|
161 str_printfa(errmsg, "%s(%s)", func, path); |
f564209e9396
eacces_error_get*(): Show current directory if path is relative.
Timo Sirainen <tss@iki.fi>
parents:
9537
diff
changeset
|
162 if (*path != '/') { |
13057
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
163 if (t_get_current_dir(&dir) == 0) { |
9589
f564209e9396
eacces_error_get*(): Show current directory if path is relative.
Timo Sirainen <tss@iki.fi>
parents:
9537
diff
changeset
|
164 str_printfa(errmsg, " in directory %s", dir); |
13057
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
165 path = t_strconcat(dir, "/", path, NULL); |
12050
8db227a70bec
access_get_error(): Fixed to give better error messages with relative paths.
Timo Sirainen <tss@iki.fi>
parents:
12004
diff
changeset
|
166 } |
9589
f564209e9396
eacces_error_get*(): Show current directory if path is relative.
Timo Sirainen <tss@iki.fi>
parents:
9537
diff
changeset
|
167 } |
f564209e9396
eacces_error_get*(): Show current directory if path is relative.
Timo Sirainen <tss@iki.fi>
parents:
9537
diff
changeset
|
168 str_printfa(errmsg, " failed: Permission denied (euid=%s", |
f564209e9396
eacces_error_get*(): Show current directory if path is relative.
Timo Sirainen <tss@iki.fi>
parents:
9537
diff
changeset
|
169 dec2str(geteuid())); |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
170 |
12859
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
171 switch (i_getpwuid(geteuid(), &pw)) { |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
172 case -1: |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
173 str_append(errmsg, "(<getpwuid() error>)"); |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
174 break; |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
175 case 0: |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
176 str_append(errmsg, "(<unknown>)"); |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
177 break; |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
178 default: |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
179 pw_name = t_strdup(pw.pw_name); |
10553
b8966b8133f2
eacces_error_get*(): Check and warn if multiple uids/gids have same name.
Timo Sirainen <tss@iki.fi>
parents:
10502
diff
changeset
|
180 str_printfa(errmsg, "(%s)", pw_name); |
12859
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
181 break; |
10553
b8966b8133f2
eacces_error_get*(): Check and warn if multiple uids/gids have same name.
Timo Sirainen <tss@iki.fi>
parents:
10502
diff
changeset
|
182 } |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
183 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
184 str_printfa(errmsg, " egid=%s", dec2str(getegid())); |
12859
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
185 switch (i_getgrgid(getegid(), &group)) { |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
186 case -1: |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
187 str_append(errmsg, "(<getgrgid() error>)"); |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
188 break; |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
189 case 0: |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
190 str_append(errmsg, "(<unknown>)"); |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
191 break; |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
192 default: |
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
193 gr_name = t_strdup(group.gr_name); |
10553
b8966b8133f2
eacces_error_get*(): Check and warn if multiple uids/gids have same name.
Timo Sirainen <tss@iki.fi>
parents:
10502
diff
changeset
|
194 str_printfa(errmsg, "(%s)", gr_name); |
12859
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
195 break; |
10553
b8966b8133f2
eacces_error_get*(): Check and warn if multiple uids/gids have same name.
Timo Sirainen <tss@iki.fi>
parents:
10502
diff
changeset
|
196 } |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
197 |
13057
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
198 prev_path = path; ret = -1; |
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
199 while (strcmp(prev_path, "/") != 0) { |
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
200 if ((p = strrchr(prev_path, '/')) == NULL) |
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
201 break; |
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
202 |
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
203 dir = t_strdup_until(prev_path, p); |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
204 ret = stat(dir, &st); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
205 if (ret == 0) |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
206 break; |
12854
46d46fa3929f
eacces_error_get*(): Handle errors to / directory better.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
207 if (errno == EACCES && strcmp(dir, "/") != 0) { |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
208 /* see if we have access to parent directory */ |
12854
46d46fa3929f
eacces_error_get*(): Handle errors to / directory better.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
209 } else if (errno == ENOENT && creating && |
46d46fa3929f
eacces_error_get*(): Handle errors to / directory better.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
210 strcmp(dir, "/") != 0) { |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
211 /* 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
|
212 parent directory we couldn't create */ |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
213 } else { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 /* 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
|
215 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
|
216 break; |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
217 } |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
218 prev_path = dir; |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
219 } |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
220 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
221 if (ret == 0) { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
222 /* dir is the first parent directory we can stat() */ |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
223 if (test_access(dir, X_OK, errmsg) < 0) { |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
224 if (errno == EACCES) |
13059
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
225 missing_mode = 1; |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
226 } else if (creating && test_access(dir, W_OK, errmsg) < 0) { |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
227 if (errno == EACCES) |
13059
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
228 missing_mode = 2; |
9501
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
229 } else if (prev_path == path && |
e22e36a61fdd
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
230 test_access(path, R_OK, errmsg) < 0) { |
9534
8760bc0b1c3a
eacces_error_get(): Check also if user had write permissions to the given file.
Timo Sirainen <tss@iki.fi>
parents:
9501
diff
changeset
|
231 } else if (!creating && test_access(path, W_OK, errmsg) < 0) { |
8760bc0b1c3a
eacces_error_get(): Check also if user had write permissions to the given file.
Timo Sirainen <tss@iki.fi>
parents:
9501
diff
changeset
|
232 /* this produces a wrong error if the operation didn't |
8760bc0b1c3a
eacces_error_get(): Check also if user had write permissions to the given file.
Timo Sirainen <tss@iki.fi>
parents:
9501
diff
changeset
|
233 actually need write permissions, but we don't know |
8760bc0b1c3a
eacces_error_get(): Check also if user had write permissions to the given file.
Timo Sirainen <tss@iki.fi>
parents:
9501
diff
changeset
|
234 it here.. */ |
13645
b6e5cf112b3e
eacces_error_get*(): Log if group has r/w permissions, but we don't belong to it.
Timo Sirainen <tss@iki.fi>
parents:
13151
diff
changeset
|
235 if (errno == EACCES) |
13059
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
236 missing_mode = 4; |
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
237 } else { |
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
238 str_append(errmsg, " UNIX perms appear ok " |
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
239 "(ACL/MAC wrong?)"); |
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
240 } |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
241 } |
13059
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
242 if (ret < 0) |
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
243 ; |
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
244 else if (st.st_uid != geteuid()) { |
13057
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
245 if (pw_name != NULL && i_getpwuid(st.st_uid, &pw) > 0 && |
12859
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
246 strcmp(pw.pw_name, pw_name) == 0) { |
10819
6a8ee83cbc8c
eacces_error_get*(): Mention if euid is parent directory's owner.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
247 str_printfa(errmsg, ", conflicting dir uid=%s(%s)", |
13057
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
248 dec2str(st.st_uid), pw_name); |
10819
6a8ee83cbc8c
eacces_error_get*(): Mention if euid is parent directory's owner.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
249 } else { |
13058
17d8e1f12901
eaccess_get_error(): Show also directory mode.
Timo Sirainen <tss@iki.fi>
parents:
13057
diff
changeset
|
250 str_printfa(errmsg, ", dir owned by %s:%s mode=0%o", |
17d8e1f12901
eaccess_get_error(): Show also directory mode.
Timo Sirainen <tss@iki.fi>
parents:
13057
diff
changeset
|
251 dec2str(st.st_uid), dec2str(st.st_gid), |
13151
8aeff3210f8d
eacces_error_get*(): Handle non-int struct stat.st_mode properly.
Timo Sirainen <tss@iki.fi>
parents:
13059
diff
changeset
|
252 (unsigned int)(st.st_mode & 0777)); |
10553
b8966b8133f2
eacces_error_get*(): Check and warn if multiple uids/gids have same name.
Timo Sirainen <tss@iki.fi>
parents:
10502
diff
changeset
|
253 } |
13059
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
254 } else if (missing_mode != 0 && |
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
255 (((st.st_mode & 0700) >> 6) & missing_mode) == 0) { |
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
256 str_append(errmsg, ", dir owner missing perms"); |
10819
6a8ee83cbc8c
eacces_error_get*(): Mention if euid is parent directory's owner.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
257 } else { |
13059
d339aeb782ed
eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents:
13058
diff
changeset
|
258 str_append(errmsg, ", UNIX perms appear ok (ACL/MAC wrong?)"); |
10553
b8966b8133f2
eacces_error_get*(): Check and warn if multiple uids/gids have same name.
Timo Sirainen <tss@iki.fi>
parents:
10502
diff
changeset
|
259 } |
13057
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
260 if (ret == 0 && gr_name != NULL && st.st_gid != getegid()) { |
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
261 if (i_getgrgid(st.st_gid, &group) > 0 && |
12859
02829f7f79c7
Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents:
12854
diff
changeset
|
262 strcmp(group.gr_name, gr_name) == 0) { |
10819
6a8ee83cbc8c
eacces_error_get*(): Mention if euid is parent directory's owner.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
263 str_printfa(errmsg, ", conflicting dir gid=%s(%s)", |
13057
12e3e8570d77
eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents:
12929
diff
changeset
|
264 dec2str(st.st_gid), gr_name); |
10553
b8966b8133f2
eacces_error_get*(): Check and warn if multiple uids/gids have same name.
Timo Sirainen <tss@iki.fi>
parents:
10502
diff
changeset
|
265 } |
b8966b8133f2
eacces_error_get*(): Check and warn if multiple uids/gids have same name.
Timo Sirainen <tss@iki.fi>
parents:
10502
diff
changeset
|
266 } |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
267 str_append_c(errmsg, ')'); |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
268 errno = orig_errno; |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
269 return str_c(errmsg); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
270 } |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
271 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
272 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
|
273 { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
274 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
|
275 } |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
276 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
277 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
|
278 { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
279 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
|
280 } |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
281 |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
282 const char *eperm_error_get_chgrp(const char *func, const char *path, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
283 gid_t gid, const char *gid_origin) |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
284 { |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
285 string_t *errmsg; |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
286 const struct group *group; |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
287 int orig_errno = errno; |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
288 |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
289 errmsg = t_str_new(256); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
290 |
12928
1319931cfda0
eperm_error_get_chgrp(): Improved error message and added a link to wiki.
Timo Sirainen <tss@iki.fi>
parents:
12859
diff
changeset
|
291 str_printfa(errmsg, "%s(%s, group=%s", func, path, dec2str(gid)); |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
292 group = getgrgid(gid); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
293 if (group != NULL) |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
294 str_printfa(errmsg, "(%s)", group->gr_name); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
295 |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
296 str_printfa(errmsg, ") failed: Operation not permitted (egid=%s", |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
297 dec2str(getegid())); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
298 group = getgrgid(getegid()); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
299 if (group != NULL) |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
300 str_printfa(errmsg, "(%s)", group->gr_name); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
301 if (gid_origin != NULL) |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
302 str_printfa(errmsg, ", group based on %s", gid_origin); |
12929
ab12bc9fcc21
eperm_error_get_chgrp(): Changed wiki link.
Timo Sirainen <tss@iki.fi>
parents:
12928
diff
changeset
|
303 str_append(errmsg, " - see http://wiki2.dovecot.org/Errors/ChgrpNoPerm)"); |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
304 errno = orig_errno; |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
305 return str_c(errmsg); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9534
diff
changeset
|
306 } |