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