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