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