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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8759
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1 /* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
6ec819adfde3 Moved user-friendly EACCES error message generation to lib/.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "str.h"
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 }