Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/eacces-error.c @ 9191:b340ecb24469 HEAD
Fix VPATH build of RQUOTA support.
Some rpcgen derive #include "..." paths from the infile argument.
This will be off for VPATH builds, as the generated rquota_xdr.c
code will look in $(srcdir), but we'll generate the rquota.h file in
$(builddir). Play safe and copy rquota.x to $(builddir) first.
This fixes the build on openSUSE 11.1.
author | Matthias Andree <matthias.andree@gmx.de> |
---|---|
date | Tue, 07 Jul 2009 21:01:36 +0200 |
parents | 2bbf175bb6d3 |
children | 6d7f6ea02e17 |
rev | line source |
---|---|
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
1 /* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */ |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "str.h" |
9148
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
5 #include "restrict-access.h" |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 #include "eacces-error.h" |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #include <sys/stat.h> |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 #include <unistd.h> |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 #include <pwd.h> |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 #include <grp.h> |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 |
9148
a32a8ea97b25
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) |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
14 { |
a32a8ea97b25
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; |
a32a8ea97b25
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; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
17 |
a32a8ea97b25
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) |
a32a8ea97b25
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; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
20 |
a32a8ea97b25
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); |
a32a8ea97b25
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++) { |
a32a8ea97b25
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) |
a32a8ea97b25
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; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
25 } |
a32a8ea97b25
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; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
27 } |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
28 |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
29 static int test_access(const char *path, int mode, string_t *errmsg) |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
30 { |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
31 struct stat st; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
32 |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
33 if (getuid() == geteuid()) { |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
34 if (access(path, mode) == 0) |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
35 return 0; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
36 |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
37 if (errno != EACCES) { |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
38 str_printfa(errmsg, " access(%s, %d) failed: %m", |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
39 path, mode); |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
40 } |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
41 return -1; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
42 } |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
43 |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
44 /* access() uses real uid, not effective uid. |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
45 we'll have to do these checks manually. */ |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
46 switch (mode) { |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
47 case X_OK: |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
48 if (stat(t_strconcat(path, "/test", NULL), &st) == 0) |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
49 return 0; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
50 if (errno == ENOENT || errno == ENOTDIR) |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
51 return 0; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
52 if (errno != EACCES) |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
53 str_printfa(errmsg, " stat(%s/test) failed: %m", path); |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
54 return -1; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
55 case R_OK: |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
56 mode = 04; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
57 break; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
58 case W_OK: |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
59 mode = 02; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
60 break; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
61 default: |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
62 i_unreached(); |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
63 } |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
64 |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
65 if (stat(path, &st) < 0) { |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
66 str_printfa(errmsg, " stat(%s) failed: %m", path); |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
67 return -1; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
68 } |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
69 |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
70 if (st.st_uid == geteuid()) |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
71 st.st_mode = (st.st_mode & 0700) >> 6; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
72 else if (is_in_group(st.st_gid)) |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
73 st.st_mode = (st.st_mode & 0070) >> 3; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
74 else |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
75 st.st_mode = (st.st_mode & 0007); |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
76 |
a32a8ea97b25
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_mode & mode) != 0) |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
78 return 0; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
79 errno = EACCES; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
80 return -1; |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
81 } |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
82 |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 static const char * |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 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
|
85 { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 const char *prev_path = path, *dir = "/", *p; |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 const struct passwd *pw; |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 const struct group *group; |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 string_t *errmsg; |
9148
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
90 struct stat st, dir_st; |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
91 int orig_errno, ret = -1; |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
93 orig_errno = errno; |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 errmsg = t_str_new(256); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 str_printfa(errmsg, "%s(%s) failed: Permission denied (euid=%s", |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 func, path, dec2str(geteuid())); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 pw = getpwuid(geteuid()); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 if (pw != NULL) |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 str_printfa(errmsg, "(%s)", pw->pw_name); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 str_printfa(errmsg, " egid=%s", dec2str(getegid())); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 group = getgrgid(getegid()); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 if (group != NULL) |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 str_printfa(errmsg, "(%s)", group->gr_name); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 while ((p = strrchr(prev_path, '/')) != NULL) { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 dir = t_strdup_until(prev_path, p); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 ret = stat(dir, &st); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 if (ret == 0) |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 break; |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 if (errno == EACCES) { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 /* see if we have access to parent directory */ |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 } else if (errno == ENOENT && creating) { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
115 /* 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
|
116 parent directory we couldn't create */ |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 } else { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 /* 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
|
119 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
|
120 break; |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 } |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
122 prev_path = dir; |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 dir = "/"; |
9148
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
124 dir_st = st; |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 } |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 if (ret == 0) { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
128 /* dir is the first parent directory we can stat() */ |
9148
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
129 if (test_access(dir, X_OK, errmsg) < 0) { |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
130 if (errno == EACCES) |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 str_printfa(errmsg, " missing +x perm: %s", dir); |
9148
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
132 } else if (creating && test_access(dir, W_OK, errmsg) < 0) { |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
133 if (errno == EACCES) |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
134 str_printfa(errmsg, " missing +w perm: %s", dir); |
9148
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
135 } else if (prev_path == path && |
a32a8ea97b25
eacces_error_get*() works now properly when process's real uid != effective uid.
Timo Sirainen <tss@iki.fi>
parents:
8759
diff
changeset
|
136 test_access(path, R_OK, errmsg) < 0) { |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
137 if (errno == EACCES) |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
138 str_printfa(errmsg, " missing +r perm: %s", path); |
9165
c69a1d0a6bd6
eacces_error_get(): Check also if user had write permissions to the given file.
Timo Sirainen <tss@iki.fi>
parents:
9148
diff
changeset
|
139 } else if (!creating && test_access(path, W_OK, errmsg) < 0) { |
c69a1d0a6bd6
eacces_error_get(): Check also if user had write permissions to the given file.
Timo Sirainen <tss@iki.fi>
parents:
9148
diff
changeset
|
140 /* this produces a wrong error if the operation didn't |
c69a1d0a6bd6
eacces_error_get(): Check also if user had write permissions to the given file.
Timo Sirainen <tss@iki.fi>
parents:
9148
diff
changeset
|
141 actually need write permissions, but we don't know |
c69a1d0a6bd6
eacces_error_get(): Check also if user had write permissions to the given file.
Timo Sirainen <tss@iki.fi>
parents:
9148
diff
changeset
|
142 it here.. */ |
c69a1d0a6bd6
eacces_error_get(): Check also if user had write permissions to the given file.
Timo Sirainen <tss@iki.fi>
parents:
9148
diff
changeset
|
143 if (errno == EACCES) |
c69a1d0a6bd6
eacces_error_get(): Check also if user had write permissions to the given file.
Timo Sirainen <tss@iki.fi>
parents:
9148
diff
changeset
|
144 str_printfa(errmsg, " missing +w perm: %s", path); |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
145 } else |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
146 str_printfa(errmsg, " UNIX perms seem ok, ACL problem?"); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
147 } |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
148 str_append_c(errmsg, ')'); |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
149 errno = orig_errno; |
8759
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
150 return str_c(errmsg); |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
151 } |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
152 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
153 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
|
154 { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
155 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
|
156 } |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
157 |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
158 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
|
159 { |
6ec819adfde3
Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
160 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
|
161 } |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
162 |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
163 const char *eperm_error_get_chgrp(const char *func, const char *path, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
164 gid_t gid, const char *gid_origin) |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
165 { |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
166 string_t *errmsg; |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
167 const struct group *group; |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
168 int orig_errno = errno; |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
169 |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
170 errmsg = t_str_new(256); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
171 |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
172 str_printfa(errmsg, "%s(%s, -1, %s", func, path, dec2str(gid)); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
173 group = getgrgid(gid); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
174 if (group != NULL) |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
175 str_printfa(errmsg, "(%s)", group->gr_name); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
176 |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
177 str_printfa(errmsg, ") failed: Operation not permitted (egid=%s", |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
178 dec2str(getegid())); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
179 group = getgrgid(getegid()); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
180 if (group != NULL) |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
181 str_printfa(errmsg, "(%s)", group->gr_name); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
182 if (gid_origin != NULL) |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
183 str_printfa(errmsg, ", group based on %s", gid_origin); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
184 str_append_c(errmsg, ')'); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
185 errno = orig_errno; |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
186 return str_c(errmsg); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9165
diff
changeset
|
187 } |