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 #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