/* * Aurélien Charbon - Bull SA * ACL testing basic program * Purpose: setting an acl on a file a verifies that the accesses are right */ #include <sys/param.h> #include <stdlib.h> #include <sys/types.h> #include <sys/time.h> #include <sys/stat.h> #include <stdio.h> #include <string.h> #include <dirent.h> #include <unistd.h> #include <errno.h> #include "config.h" #include "tst_res_flags.h" #ifdef HAVE_LIBACL #include <sys/acl.h> #define OP_READ 0x1 #define OP_WRITE 0x2 #define OP_EXEC 0x4 acl_t testacl; /* the "typical" acl used for the test */ static char *permtab[] = { "---", "r--", "-w-", "rw-", "--x", "r-x", "-wx", "rwx" }; struct statstore { /* number of passed tests */ int ok; /* number of failed tests */ int failed; } aclstat; int do_file_op(char *filename) { int exe; int result; uid_t uid; result = 0; FILE *fptr; char str[256] = "./"; fptr = malloc(sizeof(FILE)); uid = geteuid(); strcat(str, filename); exe = execl(str, NULL, NULL); if (exe == -1 && errno != EACCES) result = result + OP_EXEC; fptr = fopen(filename, "r"); if (fptr != NULL) { result = result + OP_READ; fclose(fptr); } fptr = fopen(filename, "r+"); if (fptr != NULL) { result = result + OP_WRITE; fclose(fptr); } return result; } /* acl with user entries used for the test */ acl_t test_acl_user_create(void) { char acl_text[] = "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"; acl_t acl; acl = acl_from_text(acl_text); return acl; } /* acl with group entries used for the test */ acl_t test_acl_grp_create(void) { char acl_text[] = "u::rwx,g:grp1:rwx,g:grp2:rw-,g:grp3:r--,g:grp4:r-x,g:grp5:---,g::---,o::r-x,m::rwx"; acl_t acl; acl = acl_from_text(acl_text); return acl; } acl_t test_acl_default_create(void) { char acl_text[] = "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"; acl_t acl; acl = acl_from_text(acl_text); return acl; } static void report(testnum, expected, result, fail) int testnum; /* test number */ int expected; /* expected result */ int result; /* actual result */ int fail; /* fail or warning */ { char *res; if (expected == result) { res = "[OK]"; aclstat.ok++; } else { res = "[FAILED]"; aclstat.failed++; } printf("\ttest #%d - Expected: %s - Obtained: %s - %s\n", testnum, permtab[expected], permtab[result], res); fflush(stdout); } /* * set acl in order the file is only readable for the testuser * - try to read * - try to write */ static void test1(char *file) { int result; if (seteuid((uid_t) 601) == 0) { result = do_file_op(file); /* expected result = OP_READ || OP_WRITE || OP_EXEC */ report(1, OP_READ + OP_WRITE + OP_EXEC, result); seteuid((uid_t) 0); setegid((gid_t) 0); } } /* * set acl in order the file is only readable for the testgroup * - try to read with test user * - try to write with test user * */ static void test2(char *file) { int result; if (seteuid((uid_t) 602) == 0) { result = do_file_op(file); /* expected result = OP_READ || OP_WRITE */ report(2, OP_READ + OP_WRITE, result); seteuid((uid_t) 0); } } /* * set acl in order the file is only readable for the testuser * - try to read * - try to write */ static void test3(char *file) { int result; if (seteuid((uid_t) 603) == 0) { result = do_file_op(file); /* expected result = OP_READ */ report(3, OP_READ, result); seteuid((uid_t) 0); } } /* * set read-write acl on the file for the testuser * - try to read * - try to write */ static void test4(char *file) { int result; if (seteuid((uid_t) 604) == 0) { result = do_file_op(file); /* expected result = OP_READ || OP_EXEC */ report(4, OP_READ + OP_EXEC, result); seteuid((uid_t) 0); } } static void test5(char *file) { int result; if (seteuid((uid_t) 605) == 0) { result = do_file_op(file); /* expected result = 0x0 */ report(5, 0x00, result); seteuid((uid_t) 0); } } static void testgrp1(char *file) { int result; if (setegid((gid_t) 601) == 0) { if (seteuid((uid_t) 601) == 0) { result = do_file_op(file); /* expected result = OP_READ || OP_WRITE || OP_EXEC */ report(1, OP_READ + OP_WRITE + OP_EXEC, result); seteuid((uid_t) 0); setegid((gid_t) 0); } } } /* * set acl in order the file is only readable for the testgroup * - try to read with test user * - try to write with test user * */ static void testgrp2(char *file) { int result; if ((setegid((gid_t) 602) == 0) && (seteuid((uid_t) 602) == 0)) { result = do_file_op(file); /* expected result = OP_READ || OP_WRITE */ report(2, OP_READ + OP_WRITE, result); seteuid((uid_t) 0); setegid((gid_t) 0); } } /* * set acl in order the file is only readable for the testuser * - try to read * - try to write */ static void testgrp3(char *file) { int result; if ((setegid((gid_t) 603) == 0) && (seteuid((uid_t) 603) == 0)) { result = do_file_op(file); /* expected result = OP_READ */ report(3, OP_READ, result); seteuid((uid_t) 0); setegid((gid_t) 0); } } /* * set read-write acl on the file for the testuser * - try to read * - try to write */ static void testgrp4(char *file) { int result; if (setegid((gid_t) 604) == 0) { if (seteuid((uid_t) 604) == 0) result = do_file_op(file); /* expected result = OP_READ || OP_EXEC */ report(4, OP_READ + OP_EXEC, result); seteuid((uid_t) 0); setegid((gid_t) 0); } } static void testgrp5(char *file) { int result; if (setegid((gid_t) 605) == 0) { if (seteuid((uid_t) 605) == 0) result = do_file_op(file); /* expected result = 0x0 */ report(5, 0x00, result); seteuid((uid_t) 0); setegid((gid_t) 0); } } /* testing default acl */ void test_acl_default(char *dir, acl_t acl) { /* set default acl on directory */ /* create a file in this directory */ /* compare the file's acl and the parent directory's one */ int res; acl_t acl1, acl2; res = acl_set_file(dir, ACL_TYPE_DEFAULT, acl); acl1 = acl_get_file(dir, ACL_TYPE_DEFAULT); if (res == -1) printf("path = %s **** errno = %d", dir, errno); char *path = strcat(dir, "/testfile"); fopen(path, "w+"); char *cmd = malloc(256); strcpy(cmd, "chmod 7777 "); printf(cmd); strcat(cmd, dir); system(cmd); acl2 = acl_get_file(path, ACL_TYPE_ACCESS); test1(path); test2(path); test3(path); test4(path); test5(path); } static void showstats(void) { printf("\nACL TESTS RESULTS: %d passed, %d failed\n\n", aclstat.ok, aclstat.failed); } int main(int argc, char *argv[]) { int result; aclstat.ok = 0; aclstat.failed = 0; acl_t testacl; printf("Test acl with entries on users\n"); testacl = test_acl_user_create(); /* set the right acl for the test */ result = acl_set_file(argv[1], ACL_TYPE_ACCESS, testacl); if (result == -1) { printf("setting acl on file %s failed\nBad NFS configuration", argv[1]); exit(1); } test1(argv[1]); test2(argv[1]); test3(argv[1]); test4(argv[1]); test5(argv[1]); acl_free(testacl); printf("\nTest of default acl:\n"); testacl = test_acl_default_create(); test_acl_default(argv[2], testacl); printf("\nTest acl with entries concerning groups\n"); testacl = test_acl_grp_create(); result = acl_set_file(argv[1], ACL_TYPE_ACCESS, testacl); if (result == -1) printf("setting acl on file %s failed\n", argv[1]); testgrp1(argv[1]); testgrp2(argv[1]); testgrp3(argv[1]); testgrp4(argv[1]); testgrp5(argv[1]); acl_free(testacl); showstats(); return 1; } #else int main(void) { printf("The acl library was missing upon compilation.\n"); return TCONF; } #endif /* HAVE_LIBACL */