1 /* test33: access() Author: Jan-Mark Wams (jms@cs.vu.nl) */
20 #define System(cmd) if (system_p(cmd) != 0) printf("``%s'' failed\n", cmd)
21 #define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
22 #define Stat(a,b) if (stat(a,b) != 0) printf("Can't stat %s\n", a)
23 #define Chmod(a,b) if (chmod(a,b) != 0) printf("Can't chmod %s\n", a)
24 #define Mkfifo(f) if (mkfifo(f,0777)!=0) printf("Can't make fifo %s\n", f)
26 int superuser
; /* nonzero if uid == euid (euid == 0 always) */
27 char *MaxName
; /* Name of maximum length */
28 char MaxPath
[PATH_MAX
]; /* Same for path */
29 char *ToLongName
; /* Name of maximum +1 length */
30 char ToLongPath
[PATH_MAX
+ 1]; /* Same for path, both too long */
36 void test_access(void);
37 void makelongnames(void);
39 int main(int argc
, char *argv
[])
44 if (argc
== 2) m
= atoi(argv
[1]);
49 printf("must be setuid root; test aborted\n");
54 printf("must be setuid root logged in as someone else; test aborted\n");
60 superuser
= (getuid() == 0);
62 for (i
= 0; i
< ITERATIONS
; i
++) {
63 if (m
& 0001) test33a();
64 if (m
& 0002) test33b();
65 if (m
& 0004) test33c();
66 if (m
& 0010) test33d();
73 { /* Test normal operation. */
74 int stat_loc
; /* For the wait(&stat_loc) call. */
77 System("rm -rf ../DIR_33/*");
79 /* To test normal access first make some files for real uid. */
81 case -1: printf("Can't fork\n"); break;
84 setuid(getuid()); /* (Re)set the effective ids to the
87 System("> rwx; chmod 700 rwx");
88 System("> rw_; chmod 600 rw_");
89 System("> r_x; chmod 500 r_x");
90 System("> r__; chmod 400 r__");
91 System("> _wx; chmod 300 _wx");
92 System("> _w_; chmod 200 _w_");
93 System("> __x; chmod 100 __x");
94 System("> ___; chmod 000 ___");
99 if (stat_loc
!= 0) e(1);/* Alarm? */
103 /* Let's test access() on directorys. */
105 case -1: printf("Can't fork\n"); break;
108 setuid(getuid()); /* (Re)set the effective ids to the
111 System("rm -rf [_r][_w][_x]");
112 System("mkdir rwx; chmod 700 rwx");
113 System("mkdir rw_; chmod 600 rw_");
114 System("mkdir r_x; chmod 500 r_x");
115 System("mkdir r__; chmod 400 r__");
116 System("mkdir _wx; chmod 300 _wx");
117 System("mkdir _w_; chmod 200 _w_");
118 System("mkdir __x; chmod 100 __x");
119 System("mkdir ___; chmod 000 ___");
124 if (stat_loc
!= 0) e(2);/* Alarm? */
129 case -1: printf("Can't fork\n"); break;
132 setuid(getuid()); /* (Re)set the effective ids to the
135 System("rmdir [_r][_w][_x]");
137 System("chmod 700 rwx");
139 System("chmod 600 rw_");
141 System("chmod 500 r_x");
143 System("chmod 400 r__");
145 System("chmod 300 _wx");
147 System("chmod 200 _w_");
149 System("chmod 100 __x");
151 System("chmod 000 ___");
156 if (stat_loc
!= 0) e(3);/* Alarm? */
160 /* Remove all the fifos. */
162 case -1: printf("Can't fork\n"); break;
167 System("rm -rf [_r][_w][_x]");
172 if (stat_loc
!= 0) e(4);/* Alarm? */
178 int stat_loc
; /* For the wait(&stat_loc) call. */
181 System("rm -rf ../DIR_33/*");
184 case -1: printf("Can't fork\n"); break;
188 /* (Re)set the effective ids to the real ids. */
191 System("> ______rwx; chmod 007 ______rwx");
192 System("> ________x; chmod 001 ________x");
193 System("> _________; chmod 000 _________");
198 if (stat_loc
!= 0) e(1);/* Alarm? */
201 /* If we are superuser, we have access to all. */
202 /* Well, almost, execution access might need at least one X bit. */
204 if (access("_________", R_OK
) != 0) e(2);
205 if (access("_________", W_OK
) != 0) e(3);
206 if (access("________x", R_OK
) != 0) e(4);
207 if (access("________x", W_OK
) != 0) e(5);
208 if (access("________x", X_OK
) != 0) e(6);
209 if (access("______rwx", R_OK
) != 0) e(7);
210 if (access("______rwx", W_OK
) != 0) e(8);
211 if (access("______rwx", X_OK
) != 0) e(9);
214 if (access("_________", R_OK
) != -1) e(10);
215 if (errno
!= EACCES
) e(11);
216 if (access("_________", W_OK
) != -1) e(12);
217 if (errno
!= EACCES
) e(13);
218 if (access("_________", X_OK
) != -1) e(14);
219 if (errno
!= EACCES
) e(15);
220 if (access("________x", R_OK
) != -1) e(16);
221 if (errno
!= EACCES
) e(17);
222 if (access("________x", W_OK
) != -1) e(18);
223 if (errno
!= EACCES
) e(19);
224 if (access("________x", X_OK
) != -1) e(20);
225 if (errno
!= EACCES
) e(21);
226 if (access("______rwx", R_OK
) != -1) e(22);
227 if (errno
!= EACCES
) e(23);
228 if (access("______rwx", W_OK
) != -1) e(24);
229 if (errno
!= EACCES
) e(25);
230 if (access("______rwx", X_OK
) != -1) e(26);
231 if (errno
!= EACCES
) e(27);
234 /* If the real uid != effective uid. */
236 System("rm -rf [_r][_w][_x]");
254 if (access("rwx", F_OK
) != 0) e(28);
255 if (access("rwx", R_OK
) != -1) e(29);
256 if (errno
!= EACCES
) e(30);
257 if (access("rwx", W_OK
) != -1) e(31);
258 if (errno
!= EACCES
) e(32);
259 if (access("rwx", X_OK
) != -1) e(33);
260 if (errno
!= EACCES
) e(34);
262 if (access("rw_", F_OK
) != 0) e(35);
263 if (access("rw_", R_OK
) != -1) e(36);
264 if (errno
!= EACCES
) e(37);
265 if (access("rw_", W_OK
) != -1) e(38);
266 if (errno
!= EACCES
) e(39);
267 if (access("rw_", X_OK
) != -1) e(40);
268 if (errno
!= EACCES
) e(41);
270 if (access("r_x", F_OK
) != 0) e(42);
271 if (access("r_x", R_OK
) != -1) e(43);
272 if (errno
!= EACCES
) e(44);
273 if (access("r_x", W_OK
) != -1) e(45);
274 if (errno
!= EACCES
) e(46);
275 if (access("r_x", X_OK
) != -1) e(47);
276 if (errno
!= EACCES
) e(48);
278 if (access("r__", F_OK
) != 0) e(49);
279 if (access("r__", R_OK
) != -1) e(50);
280 if (errno
!= EACCES
) e(51);
281 if (access("r__", W_OK
) != -1) e(52);
282 if (errno
!= EACCES
) e(53);
283 if (access("r__", X_OK
) != -1) e(54);
284 if (errno
!= EACCES
) e(55);
286 if (access("_wx", F_OK
) != 0) e(56);
287 if (access("_wx", R_OK
) != -1) e(57);
288 if (errno
!= EACCES
) e(58);
289 if (access("_wx", W_OK
) != -1) e(59);
290 if (errno
!= EACCES
) e(60);
291 if (access("_wx", X_OK
) != -1) e(61);
292 if (errno
!= EACCES
) e(62);
294 if (access("_w_", F_OK
) != 0) e(63);
295 if (access("_w_", R_OK
) != -1) e(64);
296 if (errno
!= EACCES
) e(65);
297 if (access("_w_", W_OK
) != -1) e(66);
298 if (errno
!= EACCES
) e(67);
299 if (access("_w_", X_OK
) != -1) e(68);
300 if (errno
!= EACCES
) e(69);
302 if (access("__x", F_OK
) != 0) e(70);
303 if (access("__x", R_OK
) != -1) e(71);
304 if (errno
!= EACCES
) e(72);
305 if (access("__x", W_OK
) != -1) e(73);
306 if (errno
!= EACCES
) e(74);
307 if (access("__x", X_OK
) != -1) e(75);
308 if (errno
!= EACCES
) e(76);
310 if (access("___", F_OK
) != 0) e(77);
311 if (access("___", R_OK
) != -1) e(78);
312 if (errno
!= EACCES
) e(79);
313 if (access("___", W_OK
) != -1) e(80);
314 if (errno
!= EACCES
) e(81);
315 if (access("___", X_OK
) != -1) e(82);
316 if (errno
!= EACCES
) e(83);
318 System("rm -rf [_r][_w][_x]");
323 { /* Test errors returned. */
324 int i
, fd
, does_truncate
;
327 System("rm -rf ../DIR_33/*");
329 /* Test what access() does with non existing files. */
330 System("rm -rf nonexist");
331 if (access("noexist", F_OK
) != -1) e(1);
332 if (errno
!= ENOENT
) e(2);
333 if (access("noexist", R_OK
) != -1) e(3);
334 if (errno
!= ENOENT
) e(4);
335 if (access("noexist", W_OK
) != -1) e(5);
336 if (errno
!= ENOENT
) e(6);
337 if (access("noexist", X_OK
) != -1) e(7);
338 if (errno
!= ENOENT
) e(8);
339 if (access("noexist", R_OK
| W_OK
) != -1) e(9);
340 if (errno
!= ENOENT
) e(10);
341 if (access("noexist", R_OK
| X_OK
) != -1) e(11);
342 if (errno
!= ENOENT
) e(12);
343 if (access("noexist", W_OK
| X_OK
) != -1) e(13);
344 if (errno
!= ENOENT
) e(14);
345 if (access("noexist", R_OK
| W_OK
| X_OK
) != -1) e(15);
346 if (errno
!= ENOENT
) e(16);
348 /* Test access on a nonsearchable path. */
349 if (mkdir("nosearch", 0777) != 0) e(1000);
350 if ( (i
= creat("nosearch/file", 0666)) < 0) e(1001);
351 if (close(i
) < 0) e(1002);
352 if ( (i
= creat("file", 0666)) < 0) e(1003);
353 if (close(i
) < 0) e(1004);
354 if (chmod("nosearch/file", 05777) < 0) e(1005);
355 if (chmod("file", 05777) < 0) e(1006);
356 if (chmod("nosearch", 0677) != 0) e(1007);
357 if (access("nosearch/file", F_OK
) != 0) e(17);
359 /* Test ToLongName and ToLongPath */
360 does_truncate
= does_fs_truncate();
362 if ((fd
= creat(ToLongName
, 0777)) == -1) e(18);
363 if (close(fd
) != 0) e(19);
364 if (access(ToLongName
, F_OK
) != 0) e(20);
366 if ((fd
= creat(ToLongName
, 0777)) != -1) e(21);
367 if (errno
!= ENAMETOOLONG
) e(22);
368 (void) close(fd
); /* Just in case */
369 if (access(ToLongName
, F_OK
) != -1) e(23);
370 if (errno
!= ENAMETOOLONG
) e(24);
373 ToLongPath
[PATH_MAX
- 2] = '/';
374 ToLongPath
[PATH_MAX
- 1] = 'a';
375 if (access(ToLongPath
, F_OK
) != -1) e(27);
376 if (errno
!= ENAMETOOLONG
) e(28);
377 ToLongPath
[PATH_MAX
- 1] = '/';
379 /* Test empty strings. */
380 if (access("", F_OK
) != -1) e(29);
381 if (errno
!= ENOENT
) e(30);
382 System("rm -rf idonotexist");
383 if (access("idonotexist", F_OK
) != -1) e(31);
384 if (errno
!= ENOENT
) e(32);
386 /* Test non directorys in prefix of path. */
387 if (access("/etc/passwd/dir/foo", F_OK
) != -1) e(33);
388 if (errno
!= ENOTDIR
) e(34);
389 System("rm -rf nodir; > nodir");
390 if (access("nodir/foo", F_OK
) != -1) e(35);
391 if (errno
!= ENOTDIR
) e(36);
393 /* Test if invalid amode arguments are signaled. */
395 Chmod("allmod", 05777);
396 for (i
= -1025; i
< 1025; i
++) {
397 if ((mode_t
) i
!= F_OK
&& ((mode_t
) i
& ~(R_OK
| W_OK
| X_OK
)) != 0) {
398 if (access("allmod", (mode_t
) i
) != -1) e(37);
399 if (errno
!= EINVAL
) e(38);
401 if (access("allmod", (mode_t
) i
) != 0) e(39);
406 { /* Test access() flags. */
407 #define EXCLUDE(a,b) (((a)^(b)) == ((a)|(b)))
409 System("rm -rf ../DIR_33/*");
411 /* The test are rather strong, stronger that POSIX specifies. */
412 /* The should be OR able, this test tests if all the 1 bits */
413 /* Are in diferent places. This should be what one wants. */
414 if (!EXCLUDE(R_OK
, W_OK
| X_OK
)) e(1);
415 if (!EXCLUDE(W_OK
, R_OK
| X_OK
)) e(2);
416 if (!EXCLUDE(X_OK
, R_OK
| W_OK
)) e(3);
417 if (F_OK
== R_OK
) e(4);
418 if (F_OK
== W_OK
) e(5);
419 if (F_OK
== X_OK
) e(6);
420 if (F_OK
== (R_OK
| W_OK
)) e(7);
421 if (F_OK
== (W_OK
| X_OK
)) e(8);
422 if (F_OK
== (R_OK
| X_OK
)) e(9);
423 if (F_OK
== (R_OK
| W_OK
| X_OK
)) e(10);
427 { /* Test all [_r][_w][_x] files. */
429 /* Test normal access. */
430 if (access("rwx", F_OK
) != 0) e(11);
431 if (access("rwx", R_OK
) != 0) e(12);
432 if (access("rwx", W_OK
) != 0) e(13);
433 if (access("rwx", X_OK
) != 0) e(14);
434 if (access("rwx", R_OK
| W_OK
) != 0) e(15);
435 if (access("rwx", R_OK
| X_OK
) != 0) e(16);
436 if (access("rwx", W_OK
| X_OK
) != 0) e(17);
437 if (access("rwx", R_OK
| W_OK
| X_OK
) != 0) e(18);
439 if (access("rw_", F_OK
) != 0) e(19);
440 if (access("rw_", R_OK
) != 0) e(20);
441 if (access("rw_", W_OK
) != 0) e(21);
442 if (access("rw_", X_OK
) != -1) e(22);
443 if (errno
!= EACCES
) e(23);
444 if (access("rw_", R_OK
| W_OK
) != 0) e(24);
445 if (access("rw_", R_OK
| X_OK
) != -1) e(25);
446 if (errno
!= EACCES
) e(26);
447 if (access("rw_", W_OK
| X_OK
) != -1) e(27);
448 if (errno
!= EACCES
) e(28);
449 if (access("rw_", R_OK
| W_OK
| X_OK
) != -1) e(29);
450 if (errno
!= EACCES
) e(30);
452 if (access("r_x", F_OK
) != 0) e(31);
453 if (access("r_x", R_OK
) != 0) e(32);
454 if (access("r_x", W_OK
) != -1) e(33);
455 if (errno
!= EACCES
) e(34);
456 if (access("r_x", X_OK
) != 0) e(35);
457 if (access("r_x", R_OK
| W_OK
) != -1) e(36);
458 if (errno
!= EACCES
) e(37);
459 if (access("r_x", R_OK
| X_OK
) != 0) e(38);
460 if (access("r_x", W_OK
| X_OK
) != -1) e(39);
461 if (errno
!= EACCES
) e(40);
462 if (access("r_x", R_OK
| W_OK
| X_OK
) != -1) e(41);
463 if (errno
!= EACCES
) e(42);
465 if (access("r__", F_OK
) != 0) e(43);
466 if (access("r__", R_OK
) != 0) e(44);
467 if (access("r__", W_OK
) != -1) e(45);
468 if (errno
!= EACCES
) e(46);
469 if (access("r__", X_OK
) != -1) e(47);
470 if (errno
!= EACCES
) e(48);
471 if (access("r__", R_OK
| W_OK
) != -1) e(49);
472 if (errno
!= EACCES
) e(50);
473 if (access("r__", R_OK
| X_OK
) != -1) e(51);
474 if (errno
!= EACCES
) e(52);
475 if (access("r__", W_OK
| X_OK
) != -1) e(53);
476 if (errno
!= EACCES
) e(54);
477 if (access("r__", R_OK
| W_OK
| X_OK
) != -1) e(55);
478 if (errno
!= EACCES
) e(56);
480 if (access("_wx", F_OK
) != 0) e(57);
481 if (access("_wx", R_OK
) != -1) e(58);
482 if (errno
!= EACCES
) e(59);
483 if (access("_wx", W_OK
) != 0) e(60);
484 if (access("_wx", X_OK
) != 0) e(61);
485 if (access("_wx", R_OK
| W_OK
) != -1) e(62);
486 if (errno
!= EACCES
) e(63);
487 if (access("_wx", R_OK
| X_OK
) != -1) e(64);
488 if (errno
!= EACCES
) e(65);
489 if (access("_wx", W_OK
| X_OK
) != 0) e(66);
490 if (access("_wx", R_OK
| W_OK
| X_OK
) != -1) e(67);
491 if (errno
!= EACCES
) e(68);
493 if (access("_w_", F_OK
) != 0) e(69);
494 if (access("_w_", R_OK
) != -1) e(70);
495 if (errno
!= EACCES
) e(71);
496 if (access("_w_", W_OK
) != 0) e(72);
497 if (access("_w_", X_OK
) != -1) e(73);
498 if (errno
!= EACCES
) e(74);
499 if (access("_w_", R_OK
| W_OK
) != -1) e(75);
500 if (errno
!= EACCES
) e(76);
501 if (access("_w_", R_OK
| X_OK
) != -1) e(77);
502 if (errno
!= EACCES
) e(78);
503 if (access("_w_", W_OK
| X_OK
) != -1) e(79);
504 if (errno
!= EACCES
) e(80);
505 if (access("_w_", R_OK
| W_OK
| X_OK
) != -1) e(81);
506 if (errno
!= EACCES
) e(82);
508 if (access("__x", F_OK
) != 0) e(83);
509 if (access("__x", R_OK
) != -1) e(84);
510 if (errno
!= EACCES
) e(85);
511 if (access("__x", W_OK
) != -1) e(86);
512 if (errno
!= EACCES
) e(87);
513 if (access("__x", X_OK
) != 0) e(88);
514 if (access("__x", R_OK
| W_OK
) != -1) e(89);
515 if (errno
!= EACCES
) e(90);
516 if (access("__x", R_OK
| X_OK
) != -1) e(91);
517 if (errno
!= EACCES
) e(92);
518 if (access("__x", W_OK
| X_OK
) != -1) e(93);
519 if (errno
!= EACCES
) e(94);
520 if (access("__x", R_OK
| W_OK
| X_OK
) != -1) e(95);
521 if (errno
!= EACCES
) e(96);
523 if (access("___", F_OK
) != 0) e(97);
524 if (access("___", R_OK
) != -1) e(98);
525 if (errno
!= EACCES
) e(99);
526 if (access("___", W_OK
) != -1) e(100);
527 if (errno
!= EACCES
) e(101);
528 if (access("___", X_OK
) != -1) e(102);
529 if (errno
!= EACCES
) e(103);
530 if (access("___", R_OK
| W_OK
) != -1) e(104);
531 if (errno
!= EACCES
) e(105);
532 if (access("___", R_OK
| X_OK
) != -1) e(106);
533 if (errno
!= EACCES
) e(107);
534 if (access("___", W_OK
| X_OK
) != -1) e(108);
535 if (errno
!= EACCES
) e(109);
536 if (access("___", R_OK
| W_OK
| X_OK
) != -1) e(110);
537 if (errno
!= EACCES
) e(111);
540 /* Test root access don't test X_OK on [_r][_w]_ files. */
541 if (access("rwx", F_OK
) != 0) e(112);
542 if (access("rwx", R_OK
) != 0) e(113);
543 if (access("rwx", W_OK
) != 0) e(114);
544 if (access("rwx", X_OK
) != 0) e(115);
545 if (access("rwx", R_OK
| W_OK
) != 0) e(116);
546 if (access("rwx", R_OK
| X_OK
) != 0) e(117);
547 if (access("rwx", W_OK
| X_OK
) != 0) e(118);
548 if (access("rwx", R_OK
| W_OK
| X_OK
) != 0) e(119);
550 if (access("rw_", F_OK
) != 0) e(120);
551 if (access("rw_", R_OK
) != 0) e(121);
552 if (access("rw_", W_OK
) != 0) e(122);
553 if (access("rw_", R_OK
| W_OK
) != 0) e(123);
555 if (access("r_x", F_OK
) != 0) e(124);
556 if (access("r_x", R_OK
) != 0) e(125);
557 if (access("r_x", W_OK
) != 0) e(126);
558 if (access("r_x", X_OK
) != 0) e(127);
559 if (access("r_x", R_OK
| W_OK
) != 0) e(128);
560 if (access("r_x", R_OK
| X_OK
) != 0) e(129);
561 if (access("r_x", W_OK
| X_OK
) != 0) e(130);
562 if (access("r_x", R_OK
| W_OK
| X_OK
) != 0) e(131);
564 if (access("r__", F_OK
) != 0) e(132);
565 if (access("r__", R_OK
) != 0) e(133);
566 if (access("r__", W_OK
) != 0) e(134);
567 if (access("r__", R_OK
| W_OK
) != 0) e(135);
569 if (access("_wx", F_OK
) != 0) e(136);
570 if (access("_wx", R_OK
) != 0) e(137);
571 if (access("_wx", W_OK
) != 0) e(138);
572 if (access("_wx", X_OK
) != 0) e(139);
573 if (access("_wx", R_OK
| W_OK
) != 0) e(140);
574 if (access("_wx", R_OK
| X_OK
) != 0) e(141);
575 if (access("_wx", W_OK
| X_OK
) != 0) e(142);
576 if (access("_wx", R_OK
| W_OK
| X_OK
) != 0) e(143);
578 if (access("_w_", F_OK
) != 0) e(144);
579 if (access("_w_", R_OK
) != 0) e(145);
580 if (access("_w_", W_OK
) != 0) e(146);
581 if (access("_w_", R_OK
| W_OK
) != 0) e(147);
583 if (access("__x", F_OK
) != 0) e(148);
584 if (access("__x", R_OK
) != 0) e(149);
585 if (access("__x", W_OK
) != 0) e(150);
586 if (access("__x", X_OK
) != 0) e(151);
587 if (access("__x", R_OK
| W_OK
) != 0) e(152);
588 if (access("__x", R_OK
| X_OK
) != 0) e(153);
589 if (access("__x", W_OK
| X_OK
) != 0) e(154);
590 if (access("__x", R_OK
| W_OK
| X_OK
) != 0) e(155);
592 if (access("___", F_OK
) != 0) e(156);
593 if (access("___", R_OK
) != 0) e(157);
594 if (access("___", W_OK
) != 0) e(158);
595 if (access("___", R_OK
| W_OK
) != 0) e(159);
604 max_name_length
= name_max("."); /* Aka NAME_MAX, but not every FS supports
605 * the same length, hence runtime check */
606 MaxName
= malloc(max_name_length
+ 1);
607 ToLongName
= malloc(max_name_length
+ 1 + 1); /* Name of maximum +1 length */
608 memset(MaxName
, 'a', max_name_length
);
609 MaxName
[max_name_length
] = '\0';
611 for (i
= 0; i
< PATH_MAX
- 1; i
++) { /* idem path */
615 MaxPath
[PATH_MAX
- 1] = '\0';
617 strcpy(ToLongName
, MaxName
); /* copy them Max to ToLong */
618 strcpy(ToLongPath
, MaxPath
);
620 ToLongName
[max_name_length
] = 'a';
621 ToLongName
[max_name_length
+1] = '\0';/* extend ToLongName by one too many */
622 ToLongPath
[PATH_MAX
- 1] = '/';
623 ToLongPath
[PATH_MAX
] = '\0'; /* inc ToLongPath by one */