1 /* 2 * Aurlien Charbon - Bull SA 3 * ACL testing basic program 4 * Purpose: setting an acl on a file a verifies that the accesses are right 5 */ 6 7 #include <sys/param.h> 8 9 #include <stdlib.h> 10 #include <sys/types.h> 11 #include <sys/time.h> 12 #include <sys/stat.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <dirent.h> 16 #include <unistd.h> 17 #include <errno.h> 18 19 #include "config.h" 20 #include "tst_res_flags.h" 21 22 #ifdef HAVE_LIBACL 23 24 #include <sys/acl.h> 25 26 #define OP_READ 0x1 27 #define OP_WRITE 0x2 28 #define OP_EXEC 0x4 29 30 acl_t testacl; 31 /* the "typical" acl used for the test */ 32 33 static char *permtab[] = 34 { "---", "r--", "-w-", "rw-", "--x", "r-x", "-wx", "rwx" }; 35 36 struct statstore { 37 /* number of passed tests */ 38 int ok; 39 /* number of failed tests */ 40 int failed; 41 } aclstat; 42 43 int do_file_op(char *filename) 44 { 45 int exe; 46 int result; 47 uid_t uid; 48 result = 0; 49 FILE *fptr; 50 char str[256] = "./"; 51 fptr = malloc(sizeof(FILE)); 52 53 uid = geteuid(); 54 strcat(str, filename); 55 56 exe = execl(str, NULL, NULL); 57 if (exe == -1 && errno != EACCES) 58 result = result + OP_EXEC; 59 60 fptr = fopen(filename, "r"); 61 if (fptr != NULL) { 62 result = result + OP_READ; 63 fclose(fptr); 64 } 65 66 fptr = fopen(filename, "r+"); 67 if (fptr != NULL) { 68 result = result + OP_WRITE; 69 fclose(fptr); 70 } 71 72 return result; 73 } 74 75 /* acl with user entries used for the test */ 76 acl_t test_acl_user_create(void) 77 { 78 char acl_text[] = 79 "u::rwx,u:user1:rwx,u:user2:rw-,u:user3:r--,u:user4:r-x,u:user5:---,g::r-x,o::r-x,m::rwx"; 80 acl_t acl; 81 acl = acl_from_text(acl_text); 82 return acl; 83 } 84 85 /* acl with group entries used for the test */ 86 87 acl_t test_acl_grp_create(void) 88 { 89 char acl_text[] = 90 "u::rwx,g:grp1:rwx,g:grp2:rw-,g:grp3:r--,g:grp4:r-x,g:grp5:---,g::---,o::r-x,m::rwx"; 91 acl_t acl; 92 acl = acl_from_text(acl_text); 93 return acl; 94 } 95 96 acl_t test_acl_default_create(void) 97 { 98 char acl_text[] = 99 "u::rwx,u:user1:rwx,u:user2:rw-,u:user3:r--,u:user4:r-x,u:user5:---,g::r-x,m::rwx,o::r-x"; 100 acl_t acl; 101 acl = acl_from_text(acl_text); 102 return acl; 103 } 104 105 static void report(testnum, expected, result, fail) 106 int testnum; /* test number */ 107 int expected; /* expected result */ 108 int result; /* actual result */ 109 int fail; /* fail or warning */ 110 { 111 char *res; 112 if (expected == result) { 113 res = "[OK]"; 114 aclstat.ok++; 115 } else { 116 res = "[FAILED]"; 117 aclstat.failed++; 118 } 119 printf("\ttest #%d - Expected: %s - Obtained: %s - %s\n", testnum, 120 permtab[expected], permtab[result], res); 121 122 fflush(stdout); 123 } 124 125 /* 126 * set acl in order the file is only readable for the testuser 127 * - try to read 128 * - try to write 129 */ 130 static void test1(char *file) 131 { 132 int result; 133 if (seteuid((uid_t) 601) == 0) { 134 result = do_file_op(file); 135 /* expected result = OP_READ || OP_WRITE || OP_EXEC */ 136 report(1, OP_READ + OP_WRITE + OP_EXEC, result); 137 seteuid((uid_t) 0); 138 setegid((gid_t) 0); 139 } 140 } 141 142 /* 143 * set acl in order the file is only readable for the testgroup 144 * - try to read with test user 145 * - try to write with test user 146 * 147 */ 148 149 static void test2(char *file) 150 { 151 int result; 152 if (seteuid((uid_t) 602) == 0) { 153 result = do_file_op(file); 154 /* expected result = OP_READ || OP_WRITE */ 155 report(2, OP_READ + OP_WRITE, result); 156 seteuid((uid_t) 0); 157 } 158 } 159 160 /* 161 * set acl in order the file is only readable for the testuser 162 * - try to read 163 * - try to write 164 */ 165 166 static void test3(char *file) 167 { 168 int result; 169 if (seteuid((uid_t) 603) == 0) { 170 result = do_file_op(file); 171 /* expected result = OP_READ */ 172 report(3, OP_READ, result); 173 seteuid((uid_t) 0); 174 } 175 } 176 177 /* 178 * set read-write acl on the file for the testuser 179 * - try to read 180 * - try to write 181 */ 182 183 static void test4(char *file) 184 { 185 int result; 186 if (seteuid((uid_t) 604) == 0) { 187 result = do_file_op(file); 188 /* expected result = OP_READ || OP_EXEC */ 189 report(4, OP_READ + OP_EXEC, result); 190 seteuid((uid_t) 0); 191 } 192 } 193 194 static void test5(char *file) 195 { 196 int result; 197 if (seteuid((uid_t) 605) == 0) { 198 result = do_file_op(file); 199 /* expected result = 0x0 */ 200 report(5, 0x00, result); 201 seteuid((uid_t) 0); 202 } 203 } 204 205 static void testgrp1(char *file) 206 { 207 int result; 208 if (setegid((gid_t) 601) == 0) { 209 if (seteuid((uid_t) 601) == 0) { 210 result = do_file_op(file); 211 /* expected result = OP_READ || OP_WRITE || OP_EXEC */ 212 report(1, OP_READ + OP_WRITE + OP_EXEC, result); 213 seteuid((uid_t) 0); 214 setegid((gid_t) 0); 215 } 216 } 217 } 218 219 /* 220 * set acl in order the file is only readable for the testgroup 221 * - try to read with test user 222 * - try to write with test user 223 * 224 */ 225 226 static void testgrp2(char *file) 227 { 228 int result; 229 if ((setegid((gid_t) 602) == 0) && (seteuid((uid_t) 602) == 0)) { 230 result = do_file_op(file); 231 /* expected result = OP_READ || OP_WRITE */ 232 report(2, OP_READ + OP_WRITE, result); 233 seteuid((uid_t) 0); 234 setegid((gid_t) 0); 235 } 236 } 237 238 /* 239 * set acl in order the file is only readable for the testuser 240 * - try to read 241 * - try to write 242 */ 243 244 static void testgrp3(char *file) 245 { 246 int result; 247 if ((setegid((gid_t) 603) == 0) && (seteuid((uid_t) 603) == 0)) { 248 result = do_file_op(file); 249 /* expected result = OP_READ */ 250 report(3, OP_READ, result); 251 seteuid((uid_t) 0); 252 setegid((gid_t) 0); 253 } 254 } 255 256 /* 257 * set read-write acl on the file for the testuser 258 * - try to read 259 * - try to write 260 */ 261 262 static void testgrp4(char *file) 263 { 264 int result; 265 if (setegid((gid_t) 604) == 0) { 266 if (seteuid((uid_t) 604) == 0) 267 result = do_file_op(file); 268 /* expected result = OP_READ || OP_EXEC */ 269 report(4, OP_READ + OP_EXEC, result); 270 seteuid((uid_t) 0); 271 setegid((gid_t) 0); 272 } 273 } 274 275 static void testgrp5(char *file) 276 { 277 int result; 278 if (setegid((gid_t) 605) == 0) { 279 if (seteuid((uid_t) 605) == 0) 280 result = do_file_op(file); 281 /* expected result = 0x0 */ 282 report(5, 0x00, result); 283 seteuid((uid_t) 0); 284 setegid((gid_t) 0); 285 } 286 } 287 288 /* testing default acl */ 289 void test_acl_default(char *dir, acl_t acl) 290 { 291 /* set default acl on directory */ 292 /* create a file in this directory */ 293 /* compare the file's acl and the parent directory's one */ 294 int res; 295 acl_t acl1, acl2; 296 297 res = acl_set_file(dir, ACL_TYPE_DEFAULT, acl); 298 acl1 = acl_get_file(dir, ACL_TYPE_DEFAULT); 299 if (res == -1) 300 printf("path = %s **** errno = %d", dir, errno); 301 char *path = strcat(dir, "/testfile"); 302 fopen(path, "w+"); 303 char *cmd = malloc(256); 304 305 strcpy(cmd, "chmod 7777 "); 306 printf(cmd); 307 strcat(cmd, dir); 308 system(cmd); 309 acl2 = acl_get_file(path, ACL_TYPE_ACCESS); 310 311 test1(path); 312 test2(path); 313 test3(path); 314 test4(path); 315 test5(path); 316 } 317 318 static void showstats(void) 319 { 320 printf("\nACL TESTS RESULTS: %d passed, %d failed\n\n", aclstat.ok, 321 aclstat.failed); 322 } 323 324 int main(int argc, char *argv[]) 325 { 326 int result; 327 aclstat.ok = 0; 328 aclstat.failed = 0; 329 acl_t testacl; 330 printf("Test acl with entries on users\n"); 331 testacl = test_acl_user_create(); 332 333 /* set the right acl for the test */ 334 result = acl_set_file(argv[1], ACL_TYPE_ACCESS, testacl); 335 if (result == -1) { 336 printf("setting acl on file %s failed\nBad NFS configuration", 337 argv[1]); 338 exit(1); 339 } 340 test1(argv[1]); 341 test2(argv[1]); 342 test3(argv[1]); 343 test4(argv[1]); 344 test5(argv[1]); 345 acl_free(testacl); 346 printf("\nTest of default acl:\n"); 347 348 testacl = test_acl_default_create(); 349 test_acl_default(argv[2], testacl); 350 351 printf("\nTest acl with entries concerning groups\n"); 352 testacl = test_acl_grp_create(); 353 result = acl_set_file(argv[1], ACL_TYPE_ACCESS, testacl); 354 if (result == -1) 355 printf("setting acl on file %s failed\n", argv[1]); 356 357 testgrp1(argv[1]); 358 testgrp2(argv[1]); 359 testgrp3(argv[1]); 360 testgrp4(argv[1]); 361 testgrp5(argv[1]); 362 363 acl_free(testacl); 364 365 showstats(); 366 return 1; 367 } 368 #else 369 int main(void) 370 { 371 printf("The acl library was missing upon compilation.\n"); 372 return TCONF; 373 } 374 #endif /* HAVE_LIBACL */ 375