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