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 #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
do_file_op(char * filename)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 */
test_acl_user_create(void)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
test_acl_grp_create(void)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
test_acl_default_create(void)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
report(testnum,expected,result,fail)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 */
test1(char * file)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
test2(char * file)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
test3(char * file)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
test4(char * file)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
test5(char * file)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
testgrp1(char * file)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
testgrp2(char * file)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
testgrp3(char * file)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
testgrp4(char * file)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
testgrp5(char * file)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 */
test_acl_default(char * dir,acl_t 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
showstats(void)329 static void showstats(void)
330 {
331 printf("\nACL TESTS RESULTS: %d passed, %d failed\n\n", aclstat.ok,
332 aclstat.failed);
333 }
334
main(int argc,char * argv[])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
main(void)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