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 46static uid_t uid; 47 48static 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 253static 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 265static 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 285static 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 295static 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 314static void setup(void) 315{ 316 struct passwd *pw; 317 318 pw = SAFE_GETPWNAM("nobody"); 319 320 uid = pw->pw_uid; 321 322 SAFE_TOUCH(FNAME_RWX, 0777, NULL); 323 SAFE_TOUCH(FNAME_R, 0444, NULL); 324 SAFE_TOUCH(FNAME_W, 0222, NULL); 325 SAFE_TOUCH(FNAME_X, 0111, NULL); 326 327 SAFE_MKDIR(DNAME_R, 0444); 328 SAFE_MKDIR(DNAME_W, 0222); 329 SAFE_MKDIR(DNAME_X, 0111); 330 SAFE_MKDIR(DNAME_RW, 0666); 331 SAFE_MKDIR(DNAME_RX, 0555); 332 SAFE_MKDIR(DNAME_WX, 0333); 333 334 SAFE_TOUCH(DNAME_R"/"FNAME_R, 0444, NULL); 335 SAFE_TOUCH(DNAME_R"/"FNAME_W, 0222, NULL); 336 SAFE_TOUCH(DNAME_R"/"FNAME_X, 0111, NULL); 337 338 SAFE_TOUCH(DNAME_W"/"FNAME_R, 0444, NULL); 339 SAFE_TOUCH(DNAME_W"/"FNAME_W, 0222, NULL); 340 SAFE_TOUCH(DNAME_W"/"FNAME_X, 0111, NULL); 341 342 SAFE_TOUCH(DNAME_X"/"FNAME_R, 0444, NULL); 343 SAFE_TOUCH(DNAME_X"/"FNAME_W, 0222, NULL); 344 SAFE_TOUCH(DNAME_X"/"FNAME_X, 0111, NULL); 345 346 SAFE_TOUCH(DNAME_RW"/"FNAME_R, 0444, NULL); 347 SAFE_TOUCH(DNAME_RW"/"FNAME_W, 0222, NULL); 348 SAFE_TOUCH(DNAME_RW"/"FNAME_X, 0111, NULL); 349 350 SAFE_TOUCH(DNAME_RX"/"FNAME_R, 0444, NULL); 351 SAFE_TOUCH(DNAME_RX"/"FNAME_W, 0222, NULL); 352 SAFE_TOUCH(DNAME_RX"/"FNAME_X, 0111, NULL); 353 354 SAFE_TOUCH(DNAME_WX"/"FNAME_R, 0444, NULL); 355 SAFE_TOUCH(DNAME_WX"/"FNAME_W, 0222, NULL); 356 SAFE_TOUCH(DNAME_WX"/"FNAME_X, 0111, NULL); 357} 358 359static struct tst_test test = { 360 .tid = "access01", 361 .needs_tmpdir = 1, 362 .needs_root = 1, 363 .forks_child = 1, 364 .setup = setup, 365 .test = verify_access, 366 .tcnt = ARRAY_SIZE(tcases), 367}; 368