• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3  *   AUTHOR		: William Roske
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * Further, this software is distributed without any warranty that it is
14  * free of the rightful claim of any third person regarding infringement
15  * or the like.  Any license provided herein, whether implied or
16  * otherwise, applies only to this software file.  Patent licenses, if
17  * any, provided herein do not apply to combinations of this program with
18  * other software, or any other product whatsoever.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  *
24  */
25 /*
26  * Basic test for access(2) using F_OK, R_OK, W_OK and X_OK
27  */
28 #include <errno.h>
29 #include <unistd.h>
30 #include <sys/types.h>
31 #include <pwd.h>
32 #include "tst_test.h"
33 
34 #define FNAME_RWX "accessfile_rwx"
35 #define FNAME_R   "accessfile_r"
36 #define FNAME_W   "accessfile_w"
37 #define FNAME_X   "accessfile_x"
38 
39 #define DNAME_R   "accessdir_r"
40 #define DNAME_W   "accessdir_w"
41 #define DNAME_X   "accessdir_x"
42 #define DNAME_RW  "accessdir_rw"
43 #define DNAME_RX  "accessdir_rx"
44 #define DNAME_WX  "accessdir_wx"
45 
46 static uid_t uid;
47 
48 static struct tcase {
49 	const char *fname;
50 	int mode;
51 	char *name;
52 	int exp_errno;
53 	/* 1: nobody expected  2: root expected 3: both */
54 	int exp_user;
55 } tcases[] = {
56 	{FNAME_RWX, F_OK, "F_OK", 0, 3},
57 	{FNAME_RWX, X_OK, "X_OK", 0, 3},
58 	{FNAME_RWX, W_OK, "W_OK", 0, 3},
59 	{FNAME_RWX, R_OK, "R_OK", 0, 3},
60 
61 	{FNAME_RWX, R_OK|W_OK, "R_OK|W_OK", 0, 3},
62 	{FNAME_RWX, R_OK|X_OK, "R_OK|X_OK", 0, 3},
63 	{FNAME_RWX, W_OK|X_OK, "W_OK|X_OK", 0, 3},
64 	{FNAME_RWX, R_OK|W_OK|X_OK, "R_OK|W_OK|X_OK", 0, 3},
65 
66 	{FNAME_X, X_OK, "X_OK", 0, 3},
67 	{FNAME_W, W_OK, "W_OK", 0, 3},
68 	{FNAME_R, R_OK, "R_OK", 0, 3},
69 
70 	{FNAME_R, X_OK, "X_OK", EACCES, 3},
71 	{FNAME_R, W_OK, "W_OK", EACCES, 1},
72 	{FNAME_W, R_OK, "R_OK", EACCES, 1},
73 	{FNAME_W, X_OK, "X_OK", EACCES, 3},
74 	{FNAME_X, R_OK, "R_OK", EACCES, 1},
75 	{FNAME_X, W_OK, "W_OK", EACCES, 1},
76 
77 	{FNAME_R, W_OK|X_OK, "W_OK|X_OK", EACCES, 3},
78 	{FNAME_R, R_OK|X_OK, "R_OK|X_OK", EACCES, 3},
79 	{FNAME_R, R_OK|W_OK, "R_OK|W_OK", EACCES, 1},
80 	{FNAME_R, R_OK|W_OK|X_OK, "R_OK|W_OK|X_OK", EACCES, 3},
81 
82 	{FNAME_W, W_OK|X_OK, "W_OK|X_OK", EACCES, 3},
83 	{FNAME_W, R_OK|X_OK, "R_OK|X_OK", EACCES, 3},
84 	{FNAME_W, R_OK|W_OK, "R_OK|W_OK", EACCES, 1},
85 	{FNAME_W, R_OK|W_OK|X_OK, "R_OK|W_OK|X_OK", EACCES, 3},
86 
87 	{FNAME_X, W_OK|X_OK, "W_OK|X_OK", EACCES, 1},
88 	{FNAME_X, R_OK|X_OK, "R_OK|X_OK", EACCES, 1},
89 	{FNAME_X, R_OK|W_OK, "R_OK|W_OK", EACCES, 1},
90 	{FNAME_X, R_OK|W_OK|X_OK, "R_OK|W_OK|X_OK", EACCES, 1},
91 
92 	{FNAME_R, W_OK, "W_OK", 0, 2},
93 	{FNAME_R, R_OK|W_OK, "R_OK|W_OK", 0, 2},
94 
95 	{FNAME_W, R_OK, "R_OK", 0, 2},
96 	{FNAME_W, R_OK|W_OK, "R_OK|W_OK", 0, 2},
97 
98 	{FNAME_X, R_OK, "R_OK", 0, 2},
99 	{FNAME_X, W_OK, "W_OK", 0, 2},
100 	{FNAME_X, R_OK|W_OK, "R_OK|W_OK", 0, 2},
101 
102 	{DNAME_R"/"FNAME_R, F_OK, "F_OK", 0, 2},
103 	{DNAME_R"/"FNAME_R, R_OK, "R_OK", 0, 2},
104 	{DNAME_R"/"FNAME_R, W_OK, "W_OK", 0, 2},
105 
106 	{DNAME_R"/"FNAME_W, F_OK, "F_OK", 0, 2},
107 	{DNAME_R"/"FNAME_W, R_OK, "R_OK", 0, 2},
108 	{DNAME_R"/"FNAME_W, W_OK, "W_OK", 0, 2},
109 
110 	{DNAME_R"/"FNAME_X, F_OK, "F_OK", 0, 2},
111 	{DNAME_R"/"FNAME_X, R_OK, "R_OK", 0, 2},
112 	{DNAME_R"/"FNAME_X, W_OK, "W_OK", 0, 2},
113 	{DNAME_R"/"FNAME_X, X_OK, "X_OK", 0, 2},
114 
115 	{DNAME_W"/"FNAME_R, F_OK, "F_OK", 0, 2},
116 	{DNAME_W"/"FNAME_R, R_OK, "R_OK", 0, 2},
117 	{DNAME_W"/"FNAME_R, W_OK, "W_OK", 0, 2},
118 
119 	{DNAME_W"/"FNAME_W, F_OK, "F_OK", 0, 2},
120 	{DNAME_W"/"FNAME_W, R_OK, "R_OK", 0, 2},
121 	{DNAME_W"/"FNAME_W, W_OK, "W_OK", 0, 2},
122 
123 	{DNAME_W"/"FNAME_X, F_OK, "F_OK", 0, 2},
124 	{DNAME_W"/"FNAME_X, R_OK, "R_OK", 0, 2},
125 	{DNAME_W"/"FNAME_X, W_OK, "W_OK", 0, 2},
126 	{DNAME_W"/"FNAME_X, X_OK, "X_OK", 0, 2},
127 
128 	{DNAME_X"/"FNAME_R, F_OK, "F_OK", 0, 3},
129 	{DNAME_X"/"FNAME_R, R_OK, "R_OK", 0, 3},
130 	{DNAME_X"/"FNAME_R, W_OK, "W_OK", 0, 2},
131 
132 	{DNAME_X"/"FNAME_W, F_OK, "F_OK", 0, 3},
133 	{DNAME_X"/"FNAME_W, R_OK, "R_OK", 0, 2},
134 	{DNAME_X"/"FNAME_W, W_OK, "W_OK", 0, 3},
135 
136 	{DNAME_X"/"FNAME_X, F_OK, "F_OK", 0, 3},
137 	{DNAME_X"/"FNAME_X, R_OK, "R_OK", 0, 2},
138 	{DNAME_X"/"FNAME_X, W_OK, "W_OK", 0, 2},
139 	{DNAME_X"/"FNAME_X, X_OK, "X_OK", 0, 3},
140 
141 	{DNAME_RW"/"FNAME_R, F_OK, "F_OK", 0, 2},
142 	{DNAME_RW"/"FNAME_R, R_OK, "R_OK", 0, 2},
143 	{DNAME_RW"/"FNAME_R, W_OK, "W_OK", 0, 2},
144 
145 	{DNAME_RW"/"FNAME_W, F_OK, "F_OK", 0, 2},
146 	{DNAME_RW"/"FNAME_W, R_OK, "R_OK", 0, 2},
147 	{DNAME_RW"/"FNAME_W, W_OK, "W_OK", 0, 2},
148 
149 	{DNAME_RW"/"FNAME_X, F_OK, "F_OK", 0, 2},
150 	{DNAME_RW"/"FNAME_X, R_OK, "R_OK", 0, 2},
151 	{DNAME_RW"/"FNAME_X, W_OK, "W_OK", 0, 2},
152 	{DNAME_RW"/"FNAME_X, X_OK, "X_OK", 0, 2},
153 
154 	{DNAME_RX"/"FNAME_R, F_OK, "F_OK", 0, 3},
155 	{DNAME_RX"/"FNAME_R, R_OK, "R_OK", 0, 3},
156 	{DNAME_RX"/"FNAME_R, W_OK, "W_OK", 0, 2},
157 
158 	{DNAME_RX"/"FNAME_W, F_OK, "F_OK", 0, 3},
159 	{DNAME_RX"/"FNAME_W, R_OK, "R_OK", 0, 2},
160 	{DNAME_RX"/"FNAME_W, W_OK, "W_OK", 0, 3},
161 
162 	{DNAME_RX"/"FNAME_X, F_OK, "F_OK", 0, 3},
163 	{DNAME_RX"/"FNAME_X, R_OK, "R_OK", 0, 2},
164 	{DNAME_RX"/"FNAME_X, W_OK, "W_OK", 0, 2},
165 	{DNAME_RX"/"FNAME_X, X_OK, "X_OK", 0, 3},
166 
167 	{DNAME_WX"/"FNAME_R, F_OK, "F_OK", 0, 3},
168 	{DNAME_WX"/"FNAME_R, R_OK, "R_OK", 0, 3},
169 	{DNAME_WX"/"FNAME_R, W_OK, "W_OK", 0, 2},
170 
171 	{DNAME_WX"/"FNAME_W, F_OK, "F_OK", 0, 3},
172 	{DNAME_WX"/"FNAME_W, R_OK, "R_OK", 0, 2},
173 	{DNAME_WX"/"FNAME_W, W_OK, "W_OK", 0, 3},
174 
175 	{DNAME_WX"/"FNAME_X, F_OK, "F_OK", 0, 3},
176 	{DNAME_WX"/"FNAME_X, R_OK, "R_OK", 0, 2},
177 	{DNAME_WX"/"FNAME_X, W_OK, "W_OK", 0, 2},
178 	{DNAME_WX"/"FNAME_X, X_OK, "X_OK", 0, 3},
179 
180 	{DNAME_R"/"FNAME_R, F_OK, "F_OK", EACCES, 1},
181 	{DNAME_R"/"FNAME_R, R_OK, "R_OK", EACCES, 1},
182 	{DNAME_R"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
183 	{DNAME_R"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
184 
185 	{DNAME_R"/"FNAME_W, F_OK, "F_OK", EACCES, 1},
186 	{DNAME_R"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
187 	{DNAME_R"/"FNAME_W, W_OK, "W_OK", EACCES, 1},
188 	{DNAME_R"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
189 
190 	{DNAME_R"/"FNAME_X, F_OK, "F_OK", EACCES, 1},
191 	{DNAME_R"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
192 	{DNAME_R"/"FNAME_X, W_OK, "W_OK", EACCES, 1},
193 	{DNAME_R"/"FNAME_X, X_OK, "X_OK", EACCES, 1},
194 
195 	{DNAME_W"/"FNAME_R, F_OK, "F_OK", EACCES, 1},
196 	{DNAME_W"/"FNAME_R, R_OK, "R_OK", EACCES, 1},
197 	{DNAME_W"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
198 	{DNAME_W"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
199 
200 	{DNAME_W"/"FNAME_W, F_OK, "F_OK", EACCES, 1},
201 	{DNAME_W"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
202 	{DNAME_W"/"FNAME_W, W_OK, "W_OK", EACCES, 1},
203 	{DNAME_W"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
204 
205 	{DNAME_W"/"FNAME_X, F_OK, "F_OK", EACCES, 1},
206 	{DNAME_W"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
207 	{DNAME_W"/"FNAME_X, W_OK, "W_OK", EACCES, 1},
208 	{DNAME_W"/"FNAME_X, X_OK, "X_OK", EACCES, 1},
209 
210 	{DNAME_X"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
211 	{DNAME_X"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
212 
213 	{DNAME_X"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
214 	{DNAME_X"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
215 
216 	{DNAME_X"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
217 	{DNAME_X"/"FNAME_X, W_OK, "W_OK", EACCES, 1},
218 
219 	{DNAME_RW"/"FNAME_R, F_OK, "F_OK", EACCES, 1},
220 	{DNAME_RW"/"FNAME_R, R_OK, "R_OK", EACCES, 1},
221 	{DNAME_RW"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
222 	{DNAME_RW"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
223 
224 	{DNAME_RW"/"FNAME_W, F_OK, "F_OK", EACCES, 1},
225 	{DNAME_RW"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
226 	{DNAME_RW"/"FNAME_W, W_OK, "W_OK", EACCES, 1},
227 	{DNAME_RW"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
228 
229 	{DNAME_RW"/"FNAME_X, F_OK, "F_OK", EACCES, 1},
230 	{DNAME_RW"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
231 	{DNAME_RW"/"FNAME_X, W_OK, "W_OK", EACCES, 1},
232 	{DNAME_RW"/"FNAME_X, X_OK, "X_OK", EACCES, 1},
233 
234 	{DNAME_RX"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
235 	{DNAME_RX"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
236 
237 	{DNAME_RX"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
238 	{DNAME_RX"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
239 
240 	{DNAME_RX"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
241 	{DNAME_RX"/"FNAME_X, W_OK, "W_OK", EACCES, 1},
242 
243 	{DNAME_WX"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
244 	{DNAME_WX"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
245 
246 	{DNAME_WX"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
247 	{DNAME_WX"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
248 
249 	{DNAME_WX"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
250 	{DNAME_WX"/"FNAME_X, W_OK, "W_OK", EACCES, 1}
251 };
252 
verify_success(struct tcase * tc,const char * user)253 static void verify_success(struct tcase *tc, const char *user)
254 {
255 	if (TEST_RETURN == -1) {
256 		tst_res(TFAIL | TTERRNO,
257 		        "access(%s, %s) as %s failed unexpectedly",
258 		        tc->fname, tc->name, user);
259 		return;
260 	}
261 
262 	tst_res(TPASS, "access(%s, %s) as %s", tc->fname, tc->name, user);
263 }
264 
verify_failure(struct tcase * tc,const char * user)265 static void verify_failure(struct tcase *tc, const char *user)
266 {
267 	if (TEST_RETURN != -1) {
268 		tst_res(TFAIL, "access(%s, %s) as %s succeded unexpectedly",
269 		        tc->fname, tc->name, user);
270 		return;
271 	}
272 
273 	if (TEST_ERRNO != tc->exp_errno) {
274 		tst_res(TFAIL | TTERRNO,
275 		        "access(%s, %s) as %s should fail with %s",
276 		        tc->fname, tc->name, user,
277 		        tst_strerrno(tc->exp_errno));
278 		return;
279 	}
280 
281 	tst_res(TPASS | TTERRNO, "access(%s, %s) as %s",
282 	        tc->fname, tc->name, user);
283 }
284 
access_test(struct tcase * tc,const char * user)285 static void access_test(struct tcase *tc, const char *user)
286 {
287 	TEST(access(tc->fname, tc->mode));
288 
289 	if (tc->exp_errno)
290 		verify_failure(tc, user);
291 	else
292 		verify_success(tc, user);
293 }
294 
verify_access(unsigned int n)295 static void verify_access(unsigned int n)
296 {
297 	struct tcase *tc = tcases + n;
298 	pid_t pid;
299 
300 	if (tc->exp_user & 0x02)
301 		access_test(tc, "root");
302 
303 	if (tc->exp_user & 0x01) {
304 		pid = SAFE_FORK();
305 		if (pid) {
306 			SAFE_WAITPID(pid, NULL, 0);
307 		} else {
308 			SAFE_SETUID(uid);
309 			access_test(tc, "nobody");
310 		}
311 	}
312 }
313 
setup(void)314 static void setup(void)
315 {
316 	struct passwd *pw;
317 
318 	umask(0022);
319 
320 	pw = SAFE_GETPWNAM("nobody");
321 
322 	uid = pw->pw_uid;
323 
324 	SAFE_TOUCH(FNAME_RWX, 0777, NULL);
325 	SAFE_TOUCH(FNAME_R, 0444, NULL);
326 	SAFE_TOUCH(FNAME_W, 0222, NULL);
327 	SAFE_TOUCH(FNAME_X, 0111, NULL);
328 
329 	SAFE_MKDIR(DNAME_R, 0444);
330 	SAFE_MKDIR(DNAME_W, 0222);
331 	SAFE_MKDIR(DNAME_X, 0111);
332 	SAFE_MKDIR(DNAME_RW, 0666);
333 	SAFE_MKDIR(DNAME_RX, 0555);
334 	SAFE_MKDIR(DNAME_WX, 0333);
335 
336 	SAFE_TOUCH(DNAME_R"/"FNAME_R, 0444, NULL);
337 	SAFE_TOUCH(DNAME_R"/"FNAME_W, 0222, NULL);
338 	SAFE_TOUCH(DNAME_R"/"FNAME_X, 0111, NULL);
339 
340 	SAFE_TOUCH(DNAME_W"/"FNAME_R, 0444, NULL);
341 	SAFE_TOUCH(DNAME_W"/"FNAME_W, 0222, NULL);
342 	SAFE_TOUCH(DNAME_W"/"FNAME_X, 0111, NULL);
343 
344 	SAFE_TOUCH(DNAME_X"/"FNAME_R, 0444, NULL);
345 	SAFE_TOUCH(DNAME_X"/"FNAME_W, 0222, NULL);
346 	SAFE_TOUCH(DNAME_X"/"FNAME_X, 0111, NULL);
347 
348 	SAFE_TOUCH(DNAME_RW"/"FNAME_R, 0444, NULL);
349 	SAFE_TOUCH(DNAME_RW"/"FNAME_W, 0222, NULL);
350 	SAFE_TOUCH(DNAME_RW"/"FNAME_X, 0111, NULL);
351 
352 	SAFE_TOUCH(DNAME_RX"/"FNAME_R, 0444, NULL);
353 	SAFE_TOUCH(DNAME_RX"/"FNAME_W, 0222, NULL);
354 	SAFE_TOUCH(DNAME_RX"/"FNAME_X, 0111, NULL);
355 
356 	SAFE_TOUCH(DNAME_WX"/"FNAME_R, 0444, NULL);
357 	SAFE_TOUCH(DNAME_WX"/"FNAME_W, 0222, NULL);
358 	SAFE_TOUCH(DNAME_WX"/"FNAME_X, 0111, NULL);
359 }
360 
361 static struct tst_test test = {
362 	.needs_tmpdir = 1,
363 	.needs_root = 1,
364 	.forks_child = 1,
365 	.setup = setup,
366 	.test = verify_access,
367 	.tcnt = ARRAY_SIZE(tcases),
368 };
369