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