aboutsummaryrefslogtreecommitdiffstats
path: root/src/jailtest/access.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jailtest/access.c')
-rw-r--r--src/jailtest/access.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/jailtest/access.c b/src/jailtest/access.c
new file mode 100644
index 000000000..e68227bd2
--- /dev/null
+++ b/src/jailtest/access.c
@@ -0,0 +1,124 @@
1#include "jailtest.h"
2#include <dirent.h>
3#include <sys/wait.h>
4
5typedef struct {
6 char *tfile;
7 char *tdir;
8} TestDir;
9
10#define MAX_TEST_FILES 16
11TestDir td[MAX_TEST_FILES];
12static int files_cnt = 0;
13
14void access_setup(const char *directory) {
15 // I am root!
16 assert(directory);
17 assert(user_home_dir);
18
19 if (files_cnt >= MAX_TEST_FILES) {
20 fprintf(stderr, "Error: maximum number of test directories exceded\n");
21 exit(1);
22 }
23
24 char *fname = strdup(directory);
25 if (!fname)
26 errExit("strdup");
27 if (strncmp(fname, "~/", 2) == 0) {
28 free(fname);
29 if (asprintf(&fname, "%s/%s", user_home_dir, directory + 2) == -1)
30 errExit("asprintf");
31 }
32
33 char *path = realpath(fname, NULL);
34 free(fname);
35 if (path == NULL) {
36 fprintf(stderr, "Warning: invalid directory %s, skipping...\n", directory);
37 return;
38 }
39
40 // file in home directory
41 if (strncmp(path, user_home_dir, strlen(user_home_dir)) != 0) {
42 fprintf(stderr, "Warning: file %s is not in user home directory, skipping...\n", directory);
43 free(path);
44 return;
45 }
46
47 // try to open the dir as root
48 DIR *dir = opendir(path);
49 if (!dir) {
50 fprintf(stderr, "Warning: directory %s not found, skipping\n", directory);
51 free(path);
52 return;
53 }
54 closedir(dir);
55
56 // create a test file
57 char *test_file;
58 if (asprintf(&test_file, "%s/jailtest-access-%d", path, getpid()) == -1)
59 errExit("asprintf");
60
61 FILE *fp = fopen(test_file, "w");
62 if (!fp) {
63 printf("Warning: I cannot create test file in directory %s, skipping...\n", directory);
64 return;
65 }
66 fprintf(fp, "this file was created by firetest utility, you can safely delete it\n");
67 fclose(fp);
68 int rv = chown(test_file, user_uid, user_gid);
69 if (rv)
70 errExit("chown");
71
72 char *dname = strdup(directory);
73 if (!dname)
74 errExit("strdup");
75 td[files_cnt].tdir = dname;
76 td[files_cnt].tfile = test_file;
77 files_cnt++;
78}
79
80void access_destroy(void) {
81 // remove test files
82 int i;
83
84 for (i = 0; i < files_cnt; i++) {
85 int rv = unlink(td[i].tfile);
86 (void) rv;
87 }
88 files_cnt = 0;
89}
90
91void access_test(void) {
92 // I am root in sandbox mount namespace
93 assert(user_uid);
94 int i;
95
96 pid_t child = fork();
97 if (child == -1)
98 errExit("fork");
99
100 if (child == 0) { // child
101 // drop privileges
102 if (setgid(user_gid) != 0)
103 errExit("setgid");
104 if (setuid(user_uid) != 0)
105 errExit("setuid");
106
107 for (i = 0; i < files_cnt; i++) {
108 assert(td[i].tfile);
109
110 // try to open the file for reading
111 FILE *fp = fopen(td[i].tfile, "r");
112 if (fp) {
113
114 printf(" Warning: I can read %s\n", td[i].tdir);
115 fclose(fp);
116 }
117 }
118 exit(0);
119 }
120
121 // wait for the child to finish
122 int status;
123 wait(&status);
124}