xref: /dragonfly/tools/regression/priv/test.c (revision 73610d44)
1 #include <sys/types.h>
2 #include <sys/jail.h>
3 #include <sys/wait.h>
4 #include <unistd.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 
8 void setup();
9 void teardown();
10 
11 uid_t unpriv_uid = 5000;
12 gid_t unpriv_gid = 5000;
13 
14 void
15 test(int (*fn)(), int expected, char *msg, char *msg2)
16 {
17 	int retval;
18 
19 	setup();
20 	retval = fn();
21 	teardown();
22 
23 	printf("%s (%s): ", msg, msg2);
24 
25 	if (retval == expected) {
26 		printf("OK\n");
27 	} else {
28 		printf("FAILED (was: %d, expected: %d)\n", retval, expected);
29 	}
30 	fflush(stdout);
31 }
32 
33 void
34 test_as_root(int (*fn)(), int expected, char *msg)
35 {
36 	if (getuid() != 0) {
37 		fprintf(stderr, "must be run as root\n");
38 		exit(-1);
39 	}
40 
41 	test(fn, expected, msg, "as root");
42 }
43 
44 void
45 test_as_jailed_root(int (*fn)(), int expected, char *msg)
46 {
47 	if (getuid() != 0) {
48 		fprintf(stderr, "must be run as root\n");
49 		exit(-1);
50 	}
51 
52 	int child = fork();
53 
54 	if (child == -1) {
55 		fprintf(stderr, "fork failed\n");
56 		exit(-2);
57 	}
58 
59 	if (child) {
60 		struct jail j;
61 		j.version = 1;
62 		j.path = "/";
63 		j.hostname = "jail";
64 		j.n_ips = 0;
65 
66 		int jid = jail(&j);
67 		if (jid < 0) {
68 			fprintf(stderr, "jail failed\n");
69 			exit(-1); // TODO
70 		}
71 		test(fn, expected, msg, "as jailed root");
72 		exit(0);
73 	}
74 	else {
75 		waitpid(child, NULL, 0);
76 	}
77 }
78 
79 void
80 test_as_unpriv(int (*fn)(), int expected, char *msg)
81 {
82 	if (getuid() != 0) {
83 		fprintf(stderr, "must be run as root\n");
84 		exit(-1);
85 	}
86 
87 	int child = fork();
88 
89 	if (child == -1) {
90 		fprintf(stderr, "fork failed\n");
91 		exit(-2);
92 	}
93 
94 	if (child) {
95 		setgid(unpriv_gid);
96 		setuid(unpriv_uid);
97 
98 		if (getuid() != unpriv_uid || getgid() != unpriv_gid) {
99 			fprintf(stderr, "setuid/gid failed\n");
100 			exit(-1); // TODO
101 		}
102 		test(fn, expected, msg, "as unpriv");
103 		exit(0);
104 	}
105 	else {
106 		waitpid(child, NULL, 0);
107 	}
108 }
109 
110 void
111 test_as_jailed_unpriv(int (*fn)(), int expected, char *msg)
112 {
113 	if (getuid() != 0) {
114 		fprintf(stderr, "must be run as root\n");
115 		exit(-1);
116 	}
117 
118 	int child = fork();
119 
120 	if (child == -1) {
121 		fprintf(stderr, "fork failed\n");
122 		exit(-2);
123 	}
124 
125 	if (child) {
126 		struct jail j;
127 		j.version = 1;
128 		j.path = "/";
129 		j.hostname = "jail";
130 		j.n_ips = 0;
131 
132 		int jid = jail(&j);
133 		if (jid < 0) {
134 			fprintf(stderr, "jail failed\n");
135 			exit(-1); // TODO
136 		}
137 
138 		setgid(unpriv_gid);
139 		setuid(unpriv_uid);
140 
141 		if (getuid() != unpriv_uid || getgid() != unpriv_gid) {
142 			fprintf(stderr, "setuid/gid failed\n");
143 			exit(-1); // TODO
144 		}
145 		test(fn, expected, msg, "as jailed unpriv");
146 		exit(0);
147 	}
148 	else {
149 		waitpid(child, NULL, 0);
150 	}
151 }
152