2 * Copyright (c) 2006 nCircle Network Security, Inc.
5 * This software was developed by Robert N. M. Watson for the TrustedBSD
6 * Project under contract to nCircle Network Security, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
21 * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * This is a joint test of both the read and write privileges with respect to
34 * discretionary file system access control (permissions). Only permissions,
35 * not ACL semantics, and only privilege-related checks are performed.
38 #include <sys/types.h>
50 struct test_arguments {
59 * Rather special-purpose, don't reuse. Will need updating if anything other
60 * than O_RDONLY and O_WRONLY are to be used in tests.
63 flags_to_string(int flags)
79 test_perm(struct test_arguments ta, mode_t file_mode, int expected)
81 uid_t proc_uid, file_uid;
82 gid_t proc_gid, file_gid;
86 proc_uid = ta.proc_uid;
87 proc_gid = ta.proc_gid;
88 file_uid = ta.file_uid;
89 file_gid = ta.file_gid;
90 open_flags = ta.open_flags;
92 setup_file(fpath, file_uid, file_gid, file_mode);
93 set_creds(proc_uid, proc_gid);
95 fd = open(fpath, open_flags);
99 warn("test_perm(%s, %d, %d, %d, %d, %04o, %d) "
100 "returned %d instead of %d",
101 flags_to_string(open_flags), proc_uid, proc_gid,
102 file_uid, file_gid, file_mode, expected,
111 warnx("test_perm(%s, %d, %d, %d, %d, %04o, %d)"
112 " returned 0 instead of %d",
113 flags_to_string(open_flags), proc_uid, proc_gid,
114 file_uid, file_gid, file_mode, expected,
120 } else if (errno != expected) {
121 warn("test_perm(%s, %d, %d, %d, %d, %04o, %d)"
122 " returned %d instead of %d",
123 flags_to_string(open_flags), proc_uid, proc_gid,
124 file_uid, file_gid, file_mode, expected,
136 static const gid_t gidset[] = { GID_WHEEL };
142 if (getuid() != UID_ROOT)
143 errx(-1, "must be run as root");
144 if (setgroups(1, gidset) < 0)
145 err(-1, "setgroups(1, {%d})", GID_WHEEL);
151 struct test_arguments ta;
155 ta.open_flags = O_RDONLY;
158 * Privileged user and file owner. All tests should pass.
160 ta.proc_uid = UID_ROOT;
161 ta.proc_gid = GID_WHEEL;
162 ta.file_uid = UID_ROOT;
163 ta.file_gid = GID_WHEEL;
165 test_perm(ta, 0000, 0);
166 test_perm(ta, 0100, 0);
167 test_perm(ta, 0200, 0);
168 test_perm(ta, 0300, 0);
169 test_perm(ta, 0400, 0);
170 test_perm(ta, 0500, 0);
171 test_perm(ta, 0600, 0);
172 test_perm(ta, 0700, 0);
175 * Privileged user and file group. All tests should pass.
177 ta.proc_uid = UID_ROOT;
178 ta.proc_gid = GID_WHEEL;
179 ta.file_uid = UID_OWNER;
180 ta.file_gid = GID_WHEEL;
182 test_perm(ta, 0000, 0);
183 test_perm(ta, 0010, 0);
184 test_perm(ta, 0020, 0);
185 test_perm(ta, 0030, 0);
186 test_perm(ta, 0040, 0);
187 test_perm(ta, 0050, 0);
188 test_perm(ta, 0060, 0);
189 test_perm(ta, 0070, 0);
192 * Privileged user and file other. All tests should pass.
194 ta.proc_uid = UID_ROOT;
195 ta.proc_gid = GID_WHEEL;
196 ta.file_uid = UID_OWNER;
197 ta.file_gid = GID_OWNER;
199 test_perm(ta, 0000, 0);
200 test_perm(ta, 0001, 0);
201 test_perm(ta, 0002, 0);
202 test_perm(ta, 0003, 0);
203 test_perm(ta, 0004, 0);
204 test_perm(ta, 0005, 0);
205 test_perm(ta, 0006, 0);
206 test_perm(ta, 0007, 0);
209 * Unprivileged user and file owner. Various DAC failures.
211 ta.proc_uid = UID_OWNER;
212 ta.proc_gid = GID_OWNER;
213 ta.file_uid = UID_OWNER;
214 ta.file_gid = GID_OWNER;
216 test_perm(ta, 0000, EACCES);
217 test_perm(ta, 0100, EACCES);
218 test_perm(ta, 0200, EACCES);
219 test_perm(ta, 0300, EACCES);
220 test_perm(ta, 0400, 0);
221 test_perm(ta, 0500, 0);
222 test_perm(ta, 0600, 0);
223 test_perm(ta, 0700, 0);
226 * Unprivileged user and file group. Various DAC failures.
228 ta.proc_uid = UID_OTHER;
229 ta.proc_gid = GID_OWNER;
230 ta.file_uid = UID_OWNER;
231 ta.file_gid = GID_OWNER;
233 test_perm(ta, 0000, EACCES);
234 test_perm(ta, 0010, EACCES);
235 test_perm(ta, 0020, EACCES);
236 test_perm(ta, 0030, EACCES);
237 test_perm(ta, 0040, 0);
238 test_perm(ta, 0050, 0);
239 test_perm(ta, 0060, 0);
240 test_perm(ta, 0070, 0);
243 * Unprivileged user and file other. Various DAC failures.
245 ta.proc_uid = UID_OTHER;
246 ta.proc_gid = GID_OTHER;
247 ta.file_uid = UID_OWNER;
248 ta.file_gid = GID_OWNER;
250 test_perm(ta, 0000, EACCES);
251 test_perm(ta, 0001, EACCES);
252 test_perm(ta, 0002, EACCES);
253 test_perm(ta, 0003, EACCES);
254 test_perm(ta, 0004, 0);
255 test_perm(ta, 0005, 0);
256 test_perm(ta, 0006, 0);
257 test_perm(ta, 0007, 0);
263 struct test_arguments ta;
267 ta.open_flags = O_WRONLY;
270 * Privileged user and file owner. All tests should pass.
272 ta.proc_uid = UID_ROOT;
273 ta.proc_gid = GID_WHEEL;
274 ta.file_uid = UID_ROOT;
275 ta.file_gid = GID_WHEEL;
277 test_perm(ta, 0000, 0);
278 test_perm(ta, 0100, 0);
279 test_perm(ta, 0200, 0);
280 test_perm(ta, 0300, 0);
281 test_perm(ta, 0400, 0);
282 test_perm(ta, 0500, 0);
283 test_perm(ta, 0600, 0);
284 test_perm(ta, 0700, 0);
287 * Privileged user and file group. All tests should pass.
289 ta.proc_uid = UID_ROOT;
290 ta.proc_gid = GID_WHEEL;
291 ta.file_uid = UID_OWNER;
292 ta.file_gid = GID_WHEEL;
294 test_perm(ta, 0000, 0);
295 test_perm(ta, 0010, 0);
296 test_perm(ta, 0020, 0);
297 test_perm(ta, 0030, 0);
298 test_perm(ta, 0040, 0);
299 test_perm(ta, 0050, 0);
300 test_perm(ta, 0060, 0);
301 test_perm(ta, 0070, 0);
304 * Privileged user and file other. All tests should pass.
306 ta.proc_uid = UID_ROOT;
307 ta.proc_gid = GID_WHEEL;
308 ta.file_uid = UID_OWNER;
309 ta.file_gid = GID_OWNER;
311 test_perm(ta, 0000, 0);
312 test_perm(ta, 0001, 0);
313 test_perm(ta, 0002, 0);
314 test_perm(ta, 0003, 0);
315 test_perm(ta, 0004, 0);
316 test_perm(ta, 0005, 0);
317 test_perm(ta, 0006, 0);
318 test_perm(ta, 0007, 0);
321 * Unprivileged user and file owner. Various DAC failures.
323 ta.proc_uid = UID_OWNER;
324 ta.proc_gid = GID_OWNER;
325 ta.file_uid = UID_OWNER;
326 ta.file_gid = GID_OWNER;
328 test_perm(ta, 0000, EACCES);
329 test_perm(ta, 0100, EACCES);
330 test_perm(ta, 0200, 0);
331 test_perm(ta, 0300, 0);
332 test_perm(ta, 0400, EACCES);
333 test_perm(ta, 0500, EACCES);
334 test_perm(ta, 0600, 0);
335 test_perm(ta, 0700, 0);
338 * Unprivileged user and file group. Various DAC failures.
340 ta.proc_uid = UID_OTHER;
341 ta.proc_gid = GID_OWNER;
342 ta.file_uid = UID_OWNER;
343 ta.file_gid = GID_OWNER;
345 test_perm(ta, 0000, EACCES);
346 test_perm(ta, 0010, EACCES);
347 test_perm(ta, 0020, 0);
348 test_perm(ta, 0030, 0);
349 test_perm(ta, 0040, EACCES);
350 test_perm(ta, 0050, EACCES);
351 test_perm(ta, 0060, 0);
352 test_perm(ta, 0070, 0);
355 * Unprivileged user and file other. Various DAC failures.
357 ta.proc_uid = UID_OTHER;
358 ta.proc_gid = GID_OTHER;
359 ta.file_uid = UID_OWNER;
360 ta.file_gid = GID_OWNER;
362 test_perm(ta, 0000, EACCES);
363 test_perm(ta, 0001, EACCES);
364 test_perm(ta, 0002, 0);
365 test_perm(ta, 0003, 0);
366 test_perm(ta, 0004, EACCES);
367 test_perm(ta, 0005, EACCES);
368 test_perm(ta, 0006, 0);
369 test_perm(ta, 0007, 0);