annotate src/lib/eacces-error.c @ 22656:1789bf2a1e01

director: Make sure HOST-RESET-USERS isn't used with max_moving_users=0 The reset command would just hang in that case. doveadm would never have sent this, so this is just an extra sanity check.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Sun, 05 Nov 2017 23:51:56 +0200
parents 2e2563132d5f
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 19552
diff changeset
1 /* Copyright (c) 2007-2017 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 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
113 write_eacces_error(errmsg, path, access_mode);
14255
d247d53f80b9 eacces_error_get*(): Suggest ACL/MAC error if UNIX permission bits look ok.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
114 if (test_manual_access(path, access_mode,
d247d53f80b9 eacces_error_get*(): Suggest ACL/MAC error if UNIX permission bits look ok.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
115 FALSE, errmsg) == 0) {
14256
095abcfab7f1 eacces_error_get*(): Added ',' to message to improve readability.
Timo Sirainen <tss@iki.fi>
parents: 14255
diff changeset
116 str_append(errmsg, ", UNIX perms appear ok "
14255
d247d53f80b9 eacces_error_get*(): Suggest ACL/MAC error if UNIX permission bits look ok.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
117 "(ACL/MAC wrong?)");
d247d53f80b9 eacces_error_get*(): Suggest ACL/MAC error if UNIX permission bits look ok.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
118 }
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
119 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
120 } else {
14256
095abcfab7f1 eacces_error_get*(): Added ',' to message to improve readability.
Timo Sirainen <tss@iki.fi>
parents: 14255
diff changeset
121 str_printfa(errmsg, ", access(%s, %d) failed: %m",
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
122 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
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 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
125 }
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
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 /* 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
128 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
129 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
130 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
131 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
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 == 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
134 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
135 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
136 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
137 else
14256
095abcfab7f1 eacces_error_get*(): Added ',' to message to improve readability.
Timo Sirainen <tss@iki.fi>
parents: 14255
diff changeset
138 str_printfa(errmsg, ", stat(%s/test) failed: %m", path);
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
139 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
140 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
141 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
142 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
143 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
144 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
145 }
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 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
148 }
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
149
8759
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150 static const char *
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151 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
152 {
13057
12e3e8570d77 eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents: 12929
diff changeset
153 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
154 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
155 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
156 struct group group;
8759
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
157 string_t *errmsg;
13057
12e3e8570d77 eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents: 12929
diff changeset
158 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
159 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
160
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
161 orig_errno = errno;
8759
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162 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
163 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
164 if (*path != '/') {
13057
12e3e8570d77 eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents: 12929
diff changeset
165 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
166 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
167 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
168 }
9589
f564209e9396 eacces_error_get*(): Show current directory if path is relative.
Timo Sirainen <tss@iki.fi>
parents: 9537
diff changeset
169 }
f564209e9396 eacces_error_get*(): Show current directory if path is relative.
Timo Sirainen <tss@iki.fi>
parents: 9537
diff changeset
170 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
171 dec2str(geteuid()));
8759
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172
12859
02829f7f79c7 Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents: 12854
diff changeset
173 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
174 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
175 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
176 break;
02829f7f79c7 Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents: 12854
diff changeset
177 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
178 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
179 break;
02829f7f79c7 Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents: 12854
diff changeset
180 default:
02829f7f79c7 Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents: 12854
diff changeset
181 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
182 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
183 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
184 }
8759
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
185
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
186 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
187 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
188 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
189 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
190 break;
02829f7f79c7 Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents: 12854
diff changeset
191 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
192 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
193 break;
02829f7f79c7 Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents: 12854
diff changeset
194 default:
02829f7f79c7 Replaced all getpw/gr*() to use i_getpw/gr*() with improved error handling.
Timo Sirainen <tss@iki.fi>
parents: 12854
diff changeset
195 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
196 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
197 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
198 }
8759
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
199
13057
12e3e8570d77 eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents: 12929
diff changeset
200 prev_path = path; ret = -1;
12e3e8570d77 eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents: 12929
diff changeset
201 while (strcmp(prev_path, "/") != 0) {
12e3e8570d77 eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents: 12929
diff changeset
202 if ((p = strrchr(prev_path, '/')) == NULL)
12e3e8570d77 eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents: 12929
diff changeset
203 break;
12e3e8570d77 eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents: 12929
diff changeset
204
12e3e8570d77 eaccess_get_error(): Fixes to reporting dir permissions.
Timo Sirainen <tss@iki.fi>
parents: 12929
diff changeset
205 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
206 ret = stat(dir, &st);
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
207 if (ret == 0)
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
208 break;
12854
46d46fa3929f eacces_error_get*(): Handle errors to / directory better.
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
209 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
210 /* 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
211 } else if (errno == ENOENT && creating &&
46d46fa3929f eacces_error_get*(): Handle errors to / directory better.
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
212 strcmp(dir, "/") != 0) {
8759
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
213 /* 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
214 parent directory we couldn't create */
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
215 } else {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
216 /* 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
217 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
218 break;
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 prev_path = dir;
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
221 }
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
222
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
223 if (ret == 0) {
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
224 /* 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
225 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
226 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
227 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
228 } 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
229 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
230 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
231 } 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
232 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
233 } 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
234 /* 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
235 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
236 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
237 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
238 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
239 } else {
d339aeb782ed eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents: 13058
diff changeset
240 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
241 "(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
242 }
8759
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
243 }
13059
d339aeb782ed eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents: 13058
diff changeset
244 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
245 ;
d339aeb782ed eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents: 13058
diff changeset
246 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
247 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
248 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
249 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
250 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
251 } else {
13058
17d8e1f12901 eaccess_get_error(): Show also directory mode.
Timo Sirainen <tss@iki.fi>
parents: 13057
diff changeset
252 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
253 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
254 (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
255 }
13059
d339aeb782ed eacces_get_error(): Give even better error message for directory permission errors.
Timo Sirainen <tss@iki.fi>
parents: 13058
diff changeset
256 } 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
257 (((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
258 str_append(errmsg, ", dir owner missing perms");
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 }