Home | History | Annotate | Download | only in acl
      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