• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *	Aurélien 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 
do_file_op(char * filename)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 */
test_acl_user_create(void)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 
test_acl_grp_create(void)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 
test_acl_default_create(void)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 
report(testnum,expected,result,fail)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  */
test1(char * file)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 
test2(char * file)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 
test3(char * file)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 
test4(char * file)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 
test5(char * file)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 
testgrp1(char * file)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 
testgrp2(char * file)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 
testgrp3(char * file)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 
testgrp4(char * file)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 
testgrp5(char * file)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 */
test_acl_default(char * dir,acl_t 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 
showstats(void)318 static void showstats(void)
319 {
320 	printf("\nACL TESTS RESULTS: %d passed, %d failed\n\n", aclstat.ok,
321 	       aclstat.failed);
322 }
323 
main(int argc,char * argv[])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
main(void)369 int main(void)
370 {
371 	printf("The acl library was missing upon compilation.\n");
372 	return TCONF;
373 }
374 #endif /* HAVE_LIBACL */
375