1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25: #ifndef _LIBC
26: # include <config.h>
27: # include "euidaccess.h"
28: #endif
29:
30: #include <sys/types.h>
31: #include <sys/stat.h>
32: #include <unistd.h>
33:
34: #if HAVE_LIBGEN_H
35: # include <libgen.h>
36: #endif
37:
38: #include <errno.h>
39: #ifndef __set_errno
40: # define __set_errno(val) errno = (val)
41: #endif
42:
43: #if defined EACCES && !defined EACCESS
44: # define EACCESS EACCES
45: #endif
46:
47: #ifndef F_OK
48: # define F_OK 0
49: # define X_OK 1
50: # define W_OK 2
51: # define R_OK 4
52: #endif
53:
54:
55: #ifdef _LIBC
56:
57: # define access __access
58: # define getuid __getuid
59: # define getgid __getgid
60: # define geteuid __geteuid
61: # define getegid __getegid
62: # define group_member __group_member
63: # define euidaccess __euidaccess
64: # undef stat
65: # define stat stat64
66:
67: #else
68:
69: # include "group-member.h"
70:
71: #endif
72:
73:
74:
75:
76:
77:
78:
79: int
80: euidaccess (const char *file, int mode)
81: {
82: #if defined EFF_ONLY_OK
83: return access (file, mode | EFF_ONLY_OK);
84: #elif defined ACC_SELF
85: return accessx (file, mode, ACC_SELF);
86: #elif HAVE_EACCESS
87: return eaccess (file, mode);
88: #else
89:
90: uid_t uid = getuid ();
91: gid_t gid = getgid ();
92: uid_t euid = geteuid ();
93: gid_t egid = getegid ();
94: struct stat stats;
95:
96: # if HAVE_DECL_SETREGID && PREFER_NONREENTRANT_EUIDACCESS
97:
98:
99:
100:
101:
102:
103:
104:
105: if (mode == F_OK)
106: return stat (file, &stats);
107: else
108: {
109: int result;
110: int saved_errno;
111:
112: if (uid != euid)
113: setreuid (euid, uid);
114: if (gid != egid)
115: setregid (egid, gid);
116:
117: result = access (file, mode);
118: saved_errno = errno;
119:
120:
121: if (uid != euid)
122: setreuid (uid, euid);
123: if (gid != egid)
124: setregid (gid, egid);
125:
126: errno = saved_errno;
127: return result;
128: }
129:
130: # else
131:
132:
133:
134:
135:
136: unsigned int granted;
137: if (uid == euid && gid == egid)
138:
139: return access (file, mode);
140:
141: if (stat (file, &stats) != 0)
142: return -1;
143:
144:
145:
146: if (euid == 0 && ((mode & X_OK) == 0
147: || (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
148: return 0;
149:
150:
151: if (R_OK == 4 && W_OK == 2 && X_OK == 1 && F_OK == 0)
152: mode &= 7;
153: else
154: mode = ((mode & R_OK ? 4 : 0)
155: + (mode & W_OK ? 2 : 0)
156: + (mode & X_OK ? 1 : 0));
157:
158: if (mode == 0)
159: return 0;
160:
161:
162: if (S_IRUSR == (4 << 6) && S_IWUSR == (2 << 6) && S_IXUSR == (1 << 6)
163: && S_IRGRP == (4 << 3) && S_IWGRP == (2 << 3) && S_IXGRP == (1 << 3)
164: && S_IROTH == (4 << 0) && S_IWOTH == (2 << 0) && S_IXOTH == (1 << 0))
165: granted = stats.st_mode;
166: else
167: granted = ((stats.st_mode & S_IRUSR ? 4 << 6 : 0)
168: + (stats.st_mode & S_IWUSR ? 2 << 6 : 0)
169: + (stats.st_mode & S_IXUSR ? 1 << 6 : 0)
170: + (stats.st_mode & S_IRGRP ? 4 << 3 : 0)
171: + (stats.st_mode & S_IWGRP ? 2 << 3 : 0)
172: + (stats.st_mode & S_IXGRP ? 1 << 3 : 0)
173: + (stats.st_mode & S_IROTH ? 4 << 0 : 0)
174: + (stats.st_mode & S_IWOTH ? 2 << 0 : 0)
175: + (stats.st_mode & S_IXOTH ? 1 << 0 : 0));
176:
177: if (euid == stats.st_uid)
178: granted >>= 6;
179: else if (egid == stats.st_gid || group_member (stats.st_gid))
180: granted >>= 3;
181:
182: if ((mode & ~granted) == 0)
183: return 0;
184: __set_errno (EACCESS);
185: return -1;
186:
187: # endif
188: #endif
189: }
190: #undef euidaccess
191: #ifdef weak_alias
192: weak_alias (__euidaccess, euidaccess)
193: #endif
194: ^L
195: #ifdef TEST
196: # include <error.h>
197: # include <stdio.h>
198: # include <stdlib.h>
199:
200: char *program_name;
201:
202: int
203: main (int argc, char **argv)
204: {
205: char *file;
206: int mode;
207: int err;
208:
209: program_name = argv[0];
210: if (argc < 3)
211: abort ();
212: file = argv[1];
213: mode = atoi (argv[2]);
214:
215: err = euidaccess (file, mode);
216: printf ("%d\n", err);
217: if (err != 0)
218: error (0, errno, "%s", file);
219: exit (0);
220: }
221: #endif