1162271Srwatson/*-
2162271Srwatson * Copyright (c) 2006 nCircle Network Security, Inc.
3172106Srwatson * Copyright (c) 2007 Robert N. M. Watson
4162271Srwatson * All rights reserved.
5162271Srwatson *
6162271Srwatson * This software was developed by Robert N. M. Watson for the TrustedBSD
7162271Srwatson * Project under contract to nCircle Network Security, Inc.
8162271Srwatson *
9162271Srwatson * Redistribution and use in source and binary forms, with or without
10162271Srwatson * modification, are permitted provided that the following conditions
11162271Srwatson * are met:
12162271Srwatson * 1. Redistributions of source code must retain the above copyright
13162271Srwatson *    notice, this list of conditions and the following disclaimer.
14162271Srwatson * 2. Redistributions in binary form must reproduce the above copyright
15162271Srwatson *    notice, this list of conditions and the following disclaimer in the
16162271Srwatson *    documentation and/or other materials provided with the distribution.
17162271Srwatson *
18162271Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19162271Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20162271Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21162271Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
22162271Srwatson * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23162271Srwatson * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24162271Srwatson * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25162271Srwatson * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26162271Srwatson * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27162271Srwatson * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28162271Srwatson * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29162271Srwatson *
30162271Srwatson * $FreeBSD: releng/10.2/tools/regression/priv/priv_vfs_read_write.c 172106 2007-09-09 23:08:39Z rwatson $
31162271Srwatson */
32162271Srwatson
33162271Srwatson/*
34162271Srwatson * This is a joint test of both the read and write privileges with respect to
35162271Srwatson * discretionary file system access control (permissions).  Only permissions,
36162271Srwatson * not ACL semantics, and only privilege-related checks are performed.
37162271Srwatson */
38162271Srwatson
39162271Srwatson#include <sys/types.h>
40162271Srwatson#include <sys/stat.h>
41162271Srwatson
42162271Srwatson#include <err.h>
43162271Srwatson#include <errno.h>
44162271Srwatson#include <fcntl.h>
45162271Srwatson#include <stdlib.h>
46162271Srwatson#include <string.h>
47162271Srwatson#include <unistd.h>
48162271Srwatson
49162271Srwatson#include "main.h"
50162271Srwatson
51172106Srwatsonstatic char fpath_none[1024];
52172106Srwatsonstatic char fpath_read[1024];
53172106Srwatsonstatic char fpath_write[1024];
54172106Srwatsonstatic char fpath_readwrite[1024];
55162271Srwatson
56172106Srwatsonstatic int fpath_none_initialized;
57172106Srwatsonstatic int fpath_read_initialized;
58172106Srwatsonstatic int fpath_write_initialized;
59172106Srwatsonstatic int fpath_readwrite_initialized;
60172106Srwatson
61172106Srwatsonstatic void
62172106Srwatsontry_io(const char *label, const char *fpathp, int asroot, int injail,
63172106Srwatson    int flags, int expected_error, int expected_errno)
64162271Srwatson{
65172106Srwatson	int fd;
66162271Srwatson
67172106Srwatson	fd = open(fpathp, flags);
68172106Srwatson	if (fd < 0) {
69172106Srwatson		if (expected_error != -1)
70172106Srwatson			warnx("%s(%s, %s): expected (%d, %d) got (-1, %d)",
71172106Srwatson			    label, asroot ? "root" : "!root", injail ? "jail"
72172106Srwatson			    : "!jail", expected_error, expected_errno, errno);
73172106Srwatson	} else {
74172106Srwatson		if (expected_error == -1)
75172106Srwatson			warnx("%s(%s, %s): expected (%d, %d) got 0", label,
76172106Srwatson			    asroot ? "root" : "!root", injail ? "jail" :
77172106Srwatson			    "!jail", expected_error, expected_errno);
78172106Srwatson		(void)close(fd);
79162271Srwatson	}
80162271Srwatson}
81162271Srwatson
82172106Srwatsonint
83172106Srwatsonpriv_vfs_readwrite_fowner_setup(int asroot, int injail, struct test *test)
84162271Srwatson{
85162271Srwatson
86172106Srwatson	setup_file("priv_vfs_readwrite_fowner_setup: fpath_none", fpath_none,
87172106Srwatson	    asroot ? UID_ROOT : UID_OWNER, GID_OTHER, 0000);
88172106Srwatson	fpath_none_initialized = 1;
89172106Srwatson	setup_file("priv_vfs_readwrite_fowner_setup: fpath_read", fpath_read,
90172106Srwatson	    asroot ? UID_ROOT : UID_OWNER, GID_OTHER, 0400);
91172106Srwatson	fpath_read_initialized = 1;
92172106Srwatson	setup_file("priv_vfs_readwrite_fowner_setup: fpath_write",
93172106Srwatson	    fpath_write, asroot ? UID_ROOT : UID_OWNER, GID_OTHER, 0200);
94172106Srwatson	fpath_write_initialized = 1;
95172106Srwatson	setup_file("priv_vfs_readwrite_fowner_setup: fpath_readwrite",
96172106Srwatson	    fpath_readwrite, asroot ? UID_ROOT : UID_OWNER, GID_OTHER, 0600);
97172106Srwatson	fpath_readwrite_initialized = 1;
98172106Srwatson	return (0);
99172106Srwatson}
100162271Srwatson
101172106Srwatsonint
102172106Srwatsonpriv_vfs_readwrite_fgroup_setup(int asroot, int injail, struct test *test)
103172106Srwatson{
104162271Srwatson
105172106Srwatson	setup_file("priv_vfs_readwrite_fgroup_setup: fpath_none", fpath_none,
106172106Srwatson	    UID_OTHER, asroot ? GID_WHEEL : GID_OWNER, 0000);
107172106Srwatson	fpath_none_initialized = 1;
108172106Srwatson	setup_file("priv_vfs_readwrite_fgroup_setup: fpath_read", fpath_read,
109172106Srwatson	    UID_OTHER, asroot ? GID_WHEEL : GID_OWNER, 0040);
110172106Srwatson	fpath_read_initialized = 1;
111172106Srwatson	setup_file("priv_vfs_readwrite_fgroup_setup: fpath_write",
112172106Srwatson	    fpath_write, UID_OTHER, asroot ? GID_WHEEL : GID_OWNER, 0020);
113172106Srwatson	fpath_write_initialized = 1;
114172106Srwatson	setup_file("priv_vfs_readwrite_fgroup_setup: fpath_readwrite",
115172106Srwatson	    fpath_readwrite, UID_OTHER, asroot ? GID_WHEEL : GID_OWNER,
116172106Srwatson	    0060);
117172106Srwatson	fpath_readwrite_initialized = 1;
118172106Srwatson	return (0);
119162271Srwatson}
120162271Srwatson
121172106Srwatsonint
122172106Srwatsonpriv_vfs_readwrite_fother_setup(int asroot, int injail, struct test *test)
123162271Srwatson{
124162271Srwatson
125172106Srwatson	setup_file("priv_vfs_readwrite_fother_setup: fpath_none", fpath_none,
126172106Srwatson	    UID_OTHER, GID_OTHER, 0000);
127172106Srwatson	fpath_none_initialized = 1;
128172106Srwatson	setup_file("priv_vfs_readwrite_fother_setup: fpath_read", fpath_read,
129172106Srwatson	    UID_OTHER, GID_OTHER, 0004);
130172106Srwatson	fpath_read_initialized = 1;
131172106Srwatson	setup_file("priv_vfs_readwrite_fother_setup: fpath_write",
132172106Srwatson	    fpath_write, UID_OTHER, GID_OTHER, 0002);
133172106Srwatson	fpath_write_initialized = 1;
134172106Srwatson	setup_file("priv_vfs_readwrite_fother_setup: fpath_readwrite",
135172106Srwatson	    fpath_readwrite, UID_OTHER, GID_OTHER, 0006);
136172106Srwatson	fpath_readwrite_initialized = 1;
137172106Srwatson	return (0);
138162271Srwatson}
139162271Srwatson
140162271Srwatsonvoid
141172106Srwatsonpriv_vfs_readwrite_fowner(int asroot, int injail, struct test *test)
142162271Srwatson{
143162271Srwatson
144172106Srwatson	try_io("priv_vfs_readwrite_fowner(none, O_RDONLY)", fpath_none,
145172106Srwatson	    asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES);
146172106Srwatson	try_io("priv_vfs_readwrite_fowner(none, O_WRONLY)", fpath_none,
147172106Srwatson	    asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES);
148172106Srwatson	try_io("priv_vfs_readwrite_fowner(none, O_RDWR)", fpath_none,
149172106Srwatson	    asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES);
150162271Srwatson
151172106Srwatson	try_io("priv_vfs_readwrite_fowner(read, O_RDONLY)", fpath_read,
152172106Srwatson	    asroot, injail, O_RDONLY, 0, 0);
153172106Srwatson	try_io("priv_vfs_readwrite_fowner(read, O_WRONLY)", fpath_read,
154172106Srwatson	    asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES);
155172106Srwatson	try_io("priv_vfs_readwrite_fowner(read, O_RDWR)", fpath_read,
156172106Srwatson	    asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES);
157162271Srwatson
158172106Srwatson	try_io("priv_vfs_readwrite_fowner(write, O_RDONLY)", fpath_write,
159172106Srwatson	    asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES);
160172106Srwatson	try_io("priv_vfs_readwrite_fowner(write, O_WRONLY)", fpath_write,
161172106Srwatson	    asroot, injail, O_WRONLY, 0, 0);
162172106Srwatson	try_io("priv_vfs_readwrite_fowner(write, O_RDWR)", fpath_write,
163172106Srwatson	    asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES);
164162271Srwatson
165172106Srwatson	try_io("priv_vfs_readwrite_fowner(write, O_RDONLY)", fpath_readwrite,
166172106Srwatson	    asroot, injail, O_RDONLY, 0, 0);
167172106Srwatson	try_io("priv_vfs_readwrite_fowner(write, O_WRONLY)", fpath_readwrite,
168172106Srwatson	    asroot, injail, O_WRONLY, 0, 0);
169172106Srwatson	try_io("priv_vfs_readwrite_fowner(write, O_RDWR)", fpath_readwrite,
170172106Srwatson	    asroot, injail, O_RDWR, 0, 0);
171172106Srwatson}
172162271Srwatson
173172106Srwatsonvoid
174172106Srwatsonpriv_vfs_readwrite_fgroup(int asroot, int injail, struct test *test)
175172106Srwatson{
176162271Srwatson
177172106Srwatson	try_io("priv_vfs_readwrite_fgroup(none, O_RDONLY)", fpath_none,
178172106Srwatson	    asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES);
179172106Srwatson	try_io("priv_vfs_readwrite_fgroup(none, O_WRONLY)", fpath_none,
180172106Srwatson	    asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES);
181172106Srwatson	try_io("priv_vfs_readwrite_fgroup(none, O_RDWR)", fpath_none,
182172106Srwatson	    asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES);
183162271Srwatson
184172106Srwatson	try_io("priv_vfs_readwrite_fgroup(read, O_RDONLY)", fpath_read,
185172106Srwatson	    asroot, injail, O_RDONLY, 0, 0);
186172106Srwatson	try_io("priv_vfs_readwrite_fgroup(read, O_WRONLY)", fpath_read,
187172106Srwatson	    asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES);
188172106Srwatson	try_io("priv_vfs_readwrite_fgroup(read, O_RDWR)", fpath_read,
189172106Srwatson	    asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES);
190162271Srwatson
191172106Srwatson	try_io("priv_vfs_readwrite_fgroup(write, O_RDONLY)", fpath_write,
192172106Srwatson	    asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES);
193172106Srwatson	try_io("priv_vfs_readwrite_fgroup(write, O_WRONLY)", fpath_write,
194172106Srwatson	    asroot, injail, O_WRONLY, 0, 0);
195172106Srwatson	try_io("priv_vfs_readwrite_fgroup(write, O_RDWR)", fpath_write,
196172106Srwatson	    asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES);
197162271Srwatson
198172106Srwatson	try_io("priv_vfs_readwrite_fgroup(write, O_RDONLY)", fpath_readwrite,
199172106Srwatson	    asroot, injail, O_RDONLY, 0, 0);
200172106Srwatson	try_io("priv_vfs_readwrite_fgroup(write, O_WRONLY)", fpath_readwrite,
201172106Srwatson	    asroot, injail, O_WRONLY, 0, 0);
202172106Srwatson	try_io("priv_vfs_readwrite_fgroup(write, O_RDWR)", fpath_readwrite,
203172106Srwatson	    asroot, injail, O_RDWR, 0, 0);
204172106Srwatson}
205162271Srwatson
206172106Srwatsonvoid
207172106Srwatsonpriv_vfs_readwrite_fother(int asroot, int injail, struct test *test)
208172106Srwatson{
209162271Srwatson
210172106Srwatson	try_io("priv_vfs_readwrite_fother(none, O_RDONLY)", fpath_none,
211172106Srwatson	    asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES);
212172106Srwatson	try_io("priv_vfs_readwrite_fother(none, O_WRONLY)", fpath_none,
213172106Srwatson	    asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES);
214172106Srwatson	try_io("priv_vfs_readwrite_fother(none, O_RDWR)", fpath_none,
215172106Srwatson	    asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES);
216162271Srwatson
217172106Srwatson	try_io("priv_vfs_readwrite_fother(read, O_RDONLY)", fpath_read,
218172106Srwatson	    asroot, injail, O_RDONLY, 0, 0);
219172106Srwatson	try_io("priv_vfs_readwrite_fother(read, O_WRONLY)", fpath_read,
220172106Srwatson	    asroot, injail, O_WRONLY, asroot ? 0 : -1, EACCES);
221172106Srwatson	try_io("priv_vfs_readwrite_fother(read, O_RDWR)", fpath_read,
222172106Srwatson	    asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES);
223162271Srwatson
224172106Srwatson	try_io("priv_vfs_readwrite_fother(write, O_RDONLY)", fpath_write,
225172106Srwatson	    asroot, injail, O_RDONLY, asroot ? 0 : -1, EACCES);
226172106Srwatson	try_io("priv_vfs_readwrite_fother(write, O_WRONLY)", fpath_write,
227172106Srwatson	    asroot, injail, O_WRONLY, 0, 0);
228172106Srwatson	try_io("priv_vfs_readwrite_fother(write, O_RDWR)", fpath_write,
229172106Srwatson	    asroot, injail, O_RDWR, asroot ? 0 : -1, EACCES);
230162271Srwatson
231172106Srwatson	try_io("priv_vfs_readwrite_fother(write, O_RDONLY)", fpath_readwrite,
232172106Srwatson	    asroot, injail, O_RDONLY, 0, 0);
233172106Srwatson	try_io("priv_vfs_readwrite_fother(write, O_WRONLY)", fpath_readwrite,
234172106Srwatson	    asroot, injail, O_WRONLY, 0, 0);
235172106Srwatson	try_io("priv_vfs_readwrite_fother(write, O_RDWR)", fpath_readwrite,
236172106Srwatson	    asroot, injail, O_RDWR, 0, 0);
237162271Srwatson}
238162271Srwatson
239162271Srwatsonvoid
240172106Srwatsonpriv_vfs_readwrite_cleanup(int asroot, int injail, struct test *test)
241162271Srwatson{
242162271Srwatson
243172106Srwatson	if (fpath_none_initialized) {
244172106Srwatson		(void)unlink(fpath_none);
245172106Srwatson		fpath_none_initialized = 0;
246172106Srwatson	}
247172106Srwatson	if (fpath_read_initialized) {
248172106Srwatson		(void)unlink(fpath_read);
249172106Srwatson		fpath_read_initialized = 0;
250172106Srwatson	}
251172106Srwatson	if (fpath_write_initialized) {
252172106Srwatson		(void)unlink(fpath_write);
253172106Srwatson		fpath_write_initialized = 0;
254172106Srwatson	}
255172106Srwatson	if (fpath_readwrite_initialized) {
256172106Srwatson		(void)unlink(fpath_readwrite);
257172106Srwatson		fpath_readwrite_initialized = 0;
258172106Srwatson	}
259162271Srwatson}
260