1172106Srwatson/*-
2172106Srwatson * Copyright (c) 2006 nCircle Network Security, Inc.
3172106Srwatson * Copyright (c) 2007 Robert N. M. Watson
4172106Srwatson * All rights reserved.
5172106Srwatson *
6172106Srwatson * This software was developed by Robert N. M. Watson for the TrustedBSD
7172106Srwatson * Project under contract to nCircle Network Security, Inc.
8172106Srwatson *
9172106Srwatson * Redistribution and use in source and binary forms, with or without
10172106Srwatson * modification, are permitted provided that the following conditions
11172106Srwatson * are met:
12172106Srwatson * 1. Redistributions of source code must retain the above copyright
13172106Srwatson *    notice, this list of conditions and the following disclaimer.
14172106Srwatson * 2. Redistributions in binary form must reproduce the above copyright
15172106Srwatson *    notice, this list of conditions and the following disclaimer in the
16172106Srwatson *    documentation and/or other materials provided with the distribution.
17172106Srwatson *
18172106Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19172106Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20172106Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21172106Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
22172106Srwatson * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23172106Srwatson * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24172106Srwatson * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25172106Srwatson * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26172106Srwatson * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27172106Srwatson * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28172106Srwatson * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29172106Srwatson *
30172106Srwatson * $FreeBSD$
31172106Srwatson */
32172106Srwatson
33172106Srwatson/*
34172106Srwatson * Test NULL and non-NULL tv arguments to utimes() -- if NULL, then it is
35172106Srwatson * allowed without privilege if the owner or if write access is held.  If
36172106Srwatson * non-NULL, privilege is required even if writable.
37172106Srwatson */
38172106Srwatson
39172106Srwatson#include <sys/types.h>
40172106Srwatson#include <sys/stat.h>
41172106Srwatson
42172106Srwatson#include <err.h>
43172106Srwatson#include <errno.h>
44172106Srwatson#include <stdlib.h>
45172106Srwatson#include <string.h>
46172106Srwatson#include <unistd.h>
47172106Srwatson
48172106Srwatson#include "main.h"
49172106Srwatson
50172106Srwatsonstatic char fpath[1024];
51172106Srwatsonstatic int fpath_initialized;
52172106Srwatson
53172106Srwatsonint
54172106Srwatsonpriv_vfs_utimes_froot_setup(int asroot, int injail, struct test *test)
55172106Srwatson{
56172106Srwatson
57172106Srwatson	setup_file("priv_vfs_utimes_froot_setup: fpath", fpath,
58172106Srwatson	    UID_ROOT, GID_WHEEL, 0600);
59172106Srwatson	fpath_initialized = 1;
60172106Srwatson	return (0);
61172106Srwatson}
62172106Srwatson
63172106Srwatsonint
64172106Srwatsonpriv_vfs_utimes_fowner_setup(int asroot, int injail, struct test *test)
65172106Srwatson{
66172106Srwatson
67172106Srwatson	setup_file("priv_vfs_utimes_fowner_setup: fpath", fpath,
68172106Srwatson	    UID_OWNER, GID_OWNER, 0600);
69172106Srwatson	fpath_initialized = 1;
70172106Srwatson	return (0);
71172106Srwatson}
72172106Srwatson
73172106Srwatsonint
74172106Srwatsonpriv_vfs_utimes_fother_setup(int asroot, int injail, struct test *test)
75172106Srwatson{
76172106Srwatson
77172106Srwatson	/*
78172106Srwatson	 * In the 'other' case, we make the file writable by the test user so
79172106Srwatson	 * we can evaluate the difference between setting the time to NULL,
80172106Srwatson	 * which is possible as a writer, and non-NULL, which requires
81172106Srwatson	 * ownership.
82172106Srwatson	 */
83172106Srwatson	setup_file("priv_vfs_utimes_fother_setup: fpath", fpath,
84172106Srwatson	    UID_OTHER, GID_OTHER, 0666);
85172106Srwatson	fpath_initialized = 1;
86172106Srwatson	return (0);
87172106Srwatson}
88172106Srwatson
89172106Srwatsonvoid
90172106Srwatsonpriv_vfs_utimes_froot(int asroot, int injail, struct test *test)
91172106Srwatson{
92172106Srwatson	struct timeval tv[2];
93172106Srwatson	int error;
94172106Srwatson
95172106Srwatson	tv[0].tv_sec = 0;
96172106Srwatson	tv[0].tv_usec = 0;
97172106Srwatson	tv[1].tv_sec = 0;
98172106Srwatson	tv[1].tv_usec = 0;
99172106Srwatson	error = utimes(fpath, tv);
100172106Srwatson	if (asroot && injail)
101172106Srwatson		expect("priv_vfs_utimes_froot(root, jail)", error, 0, 0);
102172106Srwatson	if (asroot && !injail)
103172106Srwatson		expect("priv_vfs_utimes_froot(root, !jail)", error, 0, 0);
104172106Srwatson	if (!asroot && injail)
105172106Srwatson		expect("priv_vfs_utimes_froot(!root, jail)", error, -1,
106172106Srwatson		    EPERM);
107172106Srwatson	if (!asroot && !injail)
108172106Srwatson		expect("priv_vfs_utimes_froot(!root, !jail)", error, -1,
109172106Srwatson		    EPERM);
110172106Srwatson}
111172106Srwatson
112172106Srwatsonvoid
113172106Srwatsonpriv_vfs_utimes_froot_null(int asroot, int injail, struct test *test)
114172106Srwatson{
115172106Srwatson	int error;
116172106Srwatson
117172106Srwatson	error = utimes(fpath, NULL);
118172106Srwatson	if (asroot && injail)
119172106Srwatson		expect("priv_vfs_utimes_froot_null(root, jail)", error, 0,
120172106Srwatson		    0);
121172106Srwatson	if (asroot && !injail)
122172106Srwatson		expect("priv_vfs_utimes_froot_null(root, !jail)", error, 0,
123172106Srwatson		    0);
124172106Srwatson	if (!asroot && injail)
125172106Srwatson		expect("priv_vfs_utimes_froot_null(!root, jail)", error, -1,
126172106Srwatson		    EACCES);
127172106Srwatson	if (!asroot && !injail)
128172106Srwatson		expect("priv_vfs_utimes_froot_null(!root, !jail)", error, -1,
129172106Srwatson		    EACCES);
130172106Srwatson}
131172106Srwatson
132172106Srwatsonvoid
133172106Srwatsonpriv_vfs_utimes_fowner(int asroot, int injail, struct test *test)
134172106Srwatson{
135172106Srwatson	struct timeval tv[2];
136172106Srwatson	int error;
137172106Srwatson
138172106Srwatson	tv[0].tv_sec = 0;
139172106Srwatson	tv[0].tv_usec = 0;
140172106Srwatson	tv[1].tv_sec = 0;
141172106Srwatson	tv[1].tv_usec = 0;
142172106Srwatson	error = utimes(fpath, tv);
143172106Srwatson	if (asroot && injail)
144172106Srwatson		expect("priv_vfs_utimes_fowner(root, jail)", error, 0, 0);
145172106Srwatson	if (asroot && !injail)
146172106Srwatson		expect("priv_vfs_utimes_fowner(root, !jail)", error, 0, 0);
147172106Srwatson	if (!asroot && injail)
148172106Srwatson		expect("priv_vfs_utimes_fowner(!root, jail)", error, 0, 0);
149172106Srwatson	if (!asroot && !injail)
150172106Srwatson		expect("priv_vfs_utimes_fowner(!root, !jail)", error, 0, 0);
151172106Srwatson}
152172106Srwatson
153172106Srwatsonvoid
154172106Srwatsonpriv_vfs_utimes_fowner_null(int asroot, int injail, struct test *test)
155172106Srwatson{
156172106Srwatson	int error;
157172106Srwatson
158172106Srwatson	error = utimes(fpath, NULL);
159172106Srwatson	if (asroot && injail)
160172106Srwatson		expect("priv_vfs_utimes_fowner_null(root, jail)", error, 0,
161172106Srwatson		    0);
162172106Srwatson	if (asroot && !injail)
163172106Srwatson		expect("priv_vfs_utimes_fowner_null(root, !jail)", error, 0,
164172106Srwatson		    0);
165172106Srwatson	if (!asroot && injail)
166172106Srwatson		expect("priv_vfs_utimes_fowner_null(!root, jail)", error, 0,
167172106Srwatson		    0);
168172106Srwatson	if (!asroot && !injail)
169172106Srwatson		expect("priv_vfs_utimes_fowner_null(!root, !jail)", error, 0,
170172106Srwatson		    0);
171172106Srwatson}
172172106Srwatson
173172106Srwatsonvoid
174172106Srwatsonpriv_vfs_utimes_fother(int asroot, int injail, struct test *test)
175172106Srwatson{
176172106Srwatson	struct timeval tv[2];
177172106Srwatson	int error;
178172106Srwatson
179172106Srwatson	tv[0].tv_sec = 0;
180172106Srwatson	tv[0].tv_usec = 0;
181172106Srwatson	tv[1].tv_sec = 0;
182172106Srwatson	tv[1].tv_usec = 0;
183172106Srwatson	error = utimes(fpath, tv);
184172106Srwatson	if (asroot && injail)
185172106Srwatson		expect("priv_vfs_utimes_fother(root, jail)", error, 0, 0);
186172106Srwatson	if (asroot && !injail)
187172106Srwatson		expect("priv_vfs_utimes_fother(root, !jail)", error, 0, 0);
188172106Srwatson	if (!asroot && injail)
189172106Srwatson		expect("priv_vfs_utimes_fother(!root, jail)", error, -1,
190172106Srwatson		    EPERM);
191172106Srwatson	if (!asroot && !injail)
192172106Srwatson		expect("priv_vfs_utimes_fother(!root, !jail)", error, -1,
193172106Srwatson		    EPERM);
194172106Srwatson}
195172106Srwatson
196172106Srwatsonvoid
197172106Srwatsonpriv_vfs_utimes_fother_null(int asroot, int injail, struct test *test)
198172106Srwatson{
199172106Srwatson	int error;
200172106Srwatson
201172106Srwatson	error = utimes(fpath, NULL);
202172106Srwatson	if (asroot && injail)
203172106Srwatson		expect("priv_vfs_utimes_fother_null(root, jail)", error, 0,
204172106Srwatson		    0);
205172106Srwatson	if (asroot && !injail)
206172106Srwatson		expect("priv_vfs_utimes_fother_null(root, !jail)", error, 0,
207172106Srwatson		    0);
208172106Srwatson	if (!asroot && injail)
209172106Srwatson		expect("priv_vfs_utimes_fother_null(!root, jail)", error, 0,
210172106Srwatson		    0);
211172106Srwatson	if (!asroot && !injail)
212172106Srwatson		expect("priv_vfs_utimes_fother_null(!root, !jail)", error, 0,
213172106Srwatson		    0);
214172106Srwatson}
215172106Srwatson
216172106Srwatsonvoid
217172106Srwatsonpriv_vfs_utimes_cleanup(int asroot, int injail, struct test *test)
218172106Srwatson{
219172106Srwatson
220172106Srwatson	if (fpath_initialized) {
221172106Srwatson		(void)unlink(fpath);
222172106Srwatson		fpath_initialized = 0;
223172106Srwatson	}
224172106Srwatson}
225