xref: /freebsd/tools/regression/priv/priv_vfs_utimes.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
1d903306aSRobert Watson /*-
2d903306aSRobert Watson  * Copyright (c) 2006 nCircle Network Security, Inc.
3d903306aSRobert Watson  * Copyright (c) 2007 Robert N. M. Watson
4d903306aSRobert Watson  * All rights reserved.
5d903306aSRobert Watson  *
6d903306aSRobert Watson  * This software was developed by Robert N. M. Watson for the TrustedBSD
7d903306aSRobert Watson  * Project under contract to nCircle Network Security, Inc.
8d903306aSRobert Watson  *
9d903306aSRobert Watson  * Redistribution and use in source and binary forms, with or without
10d903306aSRobert Watson  * modification, are permitted provided that the following conditions
11d903306aSRobert Watson  * are met:
12d903306aSRobert Watson  * 1. Redistributions of source code must retain the above copyright
13d903306aSRobert Watson  *    notice, this list of conditions and the following disclaimer.
14d903306aSRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
15d903306aSRobert Watson  *    notice, this list of conditions and the following disclaimer in the
16d903306aSRobert Watson  *    documentation and/or other materials provided with the distribution.
17d903306aSRobert Watson  *
18d903306aSRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19d903306aSRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20d903306aSRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21d903306aSRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
22d903306aSRobert Watson  * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23d903306aSRobert Watson  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24d903306aSRobert Watson  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25d903306aSRobert Watson  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26d903306aSRobert Watson  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27d903306aSRobert Watson  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28d903306aSRobert Watson  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29d903306aSRobert Watson  */
30d903306aSRobert Watson 
31d903306aSRobert Watson /*
32d903306aSRobert Watson  * Test NULL and non-NULL tv arguments to utimes() -- if NULL, then it is
33d903306aSRobert Watson  * allowed without privilege if the owner or if write access is held.  If
34d903306aSRobert Watson  * non-NULL, privilege is required even if writable.
35d903306aSRobert Watson  */
36d903306aSRobert Watson 
37d903306aSRobert Watson #include <sys/types.h>
38d903306aSRobert Watson #include <sys/stat.h>
39d903306aSRobert Watson 
40d903306aSRobert Watson #include <err.h>
41d903306aSRobert Watson #include <errno.h>
42d903306aSRobert Watson #include <stdlib.h>
43d903306aSRobert Watson #include <string.h>
44d903306aSRobert Watson #include <unistd.h>
45d903306aSRobert Watson 
46d903306aSRobert Watson #include "main.h"
47d903306aSRobert Watson 
48d903306aSRobert Watson static char fpath[1024];
49d903306aSRobert Watson static int fpath_initialized;
50d903306aSRobert Watson 
51d903306aSRobert Watson int
priv_vfs_utimes_froot_setup(int asroot,int injail,struct test * test)52d903306aSRobert Watson priv_vfs_utimes_froot_setup(int asroot, int injail, struct test *test)
53d903306aSRobert Watson {
54d903306aSRobert Watson 
55d903306aSRobert Watson 	setup_file("priv_vfs_utimes_froot_setup: fpath", fpath,
56d903306aSRobert Watson 	    UID_ROOT, GID_WHEEL, 0600);
57d903306aSRobert Watson 	fpath_initialized = 1;
58d903306aSRobert Watson 	return (0);
59d903306aSRobert Watson }
60d903306aSRobert Watson 
61d903306aSRobert Watson int
priv_vfs_utimes_fowner_setup(int asroot,int injail,struct test * test)62d903306aSRobert Watson priv_vfs_utimes_fowner_setup(int asroot, int injail, struct test *test)
63d903306aSRobert Watson {
64d903306aSRobert Watson 
65d903306aSRobert Watson 	setup_file("priv_vfs_utimes_fowner_setup: fpath", fpath,
66d903306aSRobert Watson 	    UID_OWNER, GID_OWNER, 0600);
67d903306aSRobert Watson 	fpath_initialized = 1;
68d903306aSRobert Watson 	return (0);
69d903306aSRobert Watson }
70d903306aSRobert Watson 
71d903306aSRobert Watson int
priv_vfs_utimes_fother_setup(int asroot,int injail,struct test * test)72d903306aSRobert Watson priv_vfs_utimes_fother_setup(int asroot, int injail, struct test *test)
73d903306aSRobert Watson {
74d903306aSRobert Watson 
75d903306aSRobert Watson 	/*
76d903306aSRobert Watson 	 * In the 'other' case, we make the file writable by the test user so
77d903306aSRobert Watson 	 * we can evaluate the difference between setting the time to NULL,
78d903306aSRobert Watson 	 * which is possible as a writer, and non-NULL, which requires
79d903306aSRobert Watson 	 * ownership.
80d903306aSRobert Watson 	 */
81d903306aSRobert Watson 	setup_file("priv_vfs_utimes_fother_setup: fpath", fpath,
82d903306aSRobert Watson 	    UID_OTHER, GID_OTHER, 0666);
83d903306aSRobert Watson 	fpath_initialized = 1;
84d903306aSRobert Watson 	return (0);
85d903306aSRobert Watson }
86d903306aSRobert Watson 
87d903306aSRobert Watson void
priv_vfs_utimes_froot(int asroot,int injail,struct test * test)88d903306aSRobert Watson priv_vfs_utimes_froot(int asroot, int injail, struct test *test)
89d903306aSRobert Watson {
90d903306aSRobert Watson 	struct timeval tv[2];
91d903306aSRobert Watson 	int error;
92d903306aSRobert Watson 
93d903306aSRobert Watson 	tv[0].tv_sec = 0;
94d903306aSRobert Watson 	tv[0].tv_usec = 0;
95d903306aSRobert Watson 	tv[1].tv_sec = 0;
96d903306aSRobert Watson 	tv[1].tv_usec = 0;
97d903306aSRobert Watson 	error = utimes(fpath, tv);
98d903306aSRobert Watson 	if (asroot && injail)
99d903306aSRobert Watson 		expect("priv_vfs_utimes_froot(root, jail)", error, 0, 0);
100d903306aSRobert Watson 	if (asroot && !injail)
101d903306aSRobert Watson 		expect("priv_vfs_utimes_froot(root, !jail)", error, 0, 0);
102d903306aSRobert Watson 	if (!asroot && injail)
103d903306aSRobert Watson 		expect("priv_vfs_utimes_froot(!root, jail)", error, -1,
104d903306aSRobert Watson 		    EPERM);
105d903306aSRobert Watson 	if (!asroot && !injail)
106d903306aSRobert Watson 		expect("priv_vfs_utimes_froot(!root, !jail)", error, -1,
107d903306aSRobert Watson 		    EPERM);
108d903306aSRobert Watson }
109d903306aSRobert Watson 
110d903306aSRobert Watson void
priv_vfs_utimes_froot_null(int asroot,int injail,struct test * test)111d903306aSRobert Watson priv_vfs_utimes_froot_null(int asroot, int injail, struct test *test)
112d903306aSRobert Watson {
113d903306aSRobert Watson 	int error;
114d903306aSRobert Watson 
115d903306aSRobert Watson 	error = utimes(fpath, NULL);
116d903306aSRobert Watson 	if (asroot && injail)
117d903306aSRobert Watson 		expect("priv_vfs_utimes_froot_null(root, jail)", error, 0,
118d903306aSRobert Watson 		    0);
119d903306aSRobert Watson 	if (asroot && !injail)
120d903306aSRobert Watson 		expect("priv_vfs_utimes_froot_null(root, !jail)", error, 0,
121d903306aSRobert Watson 		    0);
122d903306aSRobert Watson 	if (!asroot && injail)
123d903306aSRobert Watson 		expect("priv_vfs_utimes_froot_null(!root, jail)", error, -1,
124d903306aSRobert Watson 		    EACCES);
125d903306aSRobert Watson 	if (!asroot && !injail)
126d903306aSRobert Watson 		expect("priv_vfs_utimes_froot_null(!root, !jail)", error, -1,
127d903306aSRobert Watson 		    EACCES);
128d903306aSRobert Watson }
129d903306aSRobert Watson 
130d903306aSRobert Watson void
priv_vfs_utimes_fowner(int asroot,int injail,struct test * test)131d903306aSRobert Watson priv_vfs_utimes_fowner(int asroot, int injail, struct test *test)
132d903306aSRobert Watson {
133d903306aSRobert Watson 	struct timeval tv[2];
134d903306aSRobert Watson 	int error;
135d903306aSRobert Watson 
136d903306aSRobert Watson 	tv[0].tv_sec = 0;
137d903306aSRobert Watson 	tv[0].tv_usec = 0;
138d903306aSRobert Watson 	tv[1].tv_sec = 0;
139d903306aSRobert Watson 	tv[1].tv_usec = 0;
140d903306aSRobert Watson 	error = utimes(fpath, tv);
141d903306aSRobert Watson 	if (asroot && injail)
142d903306aSRobert Watson 		expect("priv_vfs_utimes_fowner(root, jail)", error, 0, 0);
143d903306aSRobert Watson 	if (asroot && !injail)
144d903306aSRobert Watson 		expect("priv_vfs_utimes_fowner(root, !jail)", error, 0, 0);
145d903306aSRobert Watson 	if (!asroot && injail)
146d903306aSRobert Watson 		expect("priv_vfs_utimes_fowner(!root, jail)", error, 0, 0);
147d903306aSRobert Watson 	if (!asroot && !injail)
148d903306aSRobert Watson 		expect("priv_vfs_utimes_fowner(!root, !jail)", error, 0, 0);
149d903306aSRobert Watson }
150d903306aSRobert Watson 
151d903306aSRobert Watson void
priv_vfs_utimes_fowner_null(int asroot,int injail,struct test * test)152d903306aSRobert Watson priv_vfs_utimes_fowner_null(int asroot, int injail, struct test *test)
153d903306aSRobert Watson {
154d903306aSRobert Watson 	int error;
155d903306aSRobert Watson 
156d903306aSRobert Watson 	error = utimes(fpath, NULL);
157d903306aSRobert Watson 	if (asroot && injail)
158d903306aSRobert Watson 		expect("priv_vfs_utimes_fowner_null(root, jail)", error, 0,
159d903306aSRobert Watson 		    0);
160d903306aSRobert Watson 	if (asroot && !injail)
161d903306aSRobert Watson 		expect("priv_vfs_utimes_fowner_null(root, !jail)", error, 0,
162d903306aSRobert Watson 		    0);
163d903306aSRobert Watson 	if (!asroot && injail)
164d903306aSRobert Watson 		expect("priv_vfs_utimes_fowner_null(!root, jail)", error, 0,
165d903306aSRobert Watson 		    0);
166d903306aSRobert Watson 	if (!asroot && !injail)
167d903306aSRobert Watson 		expect("priv_vfs_utimes_fowner_null(!root, !jail)", error, 0,
168d903306aSRobert Watson 		    0);
169d903306aSRobert Watson }
170d903306aSRobert Watson 
171d903306aSRobert Watson void
priv_vfs_utimes_fother(int asroot,int injail,struct test * test)172d903306aSRobert Watson priv_vfs_utimes_fother(int asroot, int injail, struct test *test)
173d903306aSRobert Watson {
174d903306aSRobert Watson 	struct timeval tv[2];
175d903306aSRobert Watson 	int error;
176d903306aSRobert Watson 
177d903306aSRobert Watson 	tv[0].tv_sec = 0;
178d903306aSRobert Watson 	tv[0].tv_usec = 0;
179d903306aSRobert Watson 	tv[1].tv_sec = 0;
180d903306aSRobert Watson 	tv[1].tv_usec = 0;
181d903306aSRobert Watson 	error = utimes(fpath, tv);
182d903306aSRobert Watson 	if (asroot && injail)
183d903306aSRobert Watson 		expect("priv_vfs_utimes_fother(root, jail)", error, 0, 0);
184d903306aSRobert Watson 	if (asroot && !injail)
185d903306aSRobert Watson 		expect("priv_vfs_utimes_fother(root, !jail)", error, 0, 0);
186d903306aSRobert Watson 	if (!asroot && injail)
187d903306aSRobert Watson 		expect("priv_vfs_utimes_fother(!root, jail)", error, -1,
188d903306aSRobert Watson 		    EPERM);
189d903306aSRobert Watson 	if (!asroot && !injail)
190d903306aSRobert Watson 		expect("priv_vfs_utimes_fother(!root, !jail)", error, -1,
191d903306aSRobert Watson 		    EPERM);
192d903306aSRobert Watson }
193d903306aSRobert Watson 
194d903306aSRobert Watson void
priv_vfs_utimes_fother_null(int asroot,int injail,struct test * test)195d903306aSRobert Watson priv_vfs_utimes_fother_null(int asroot, int injail, struct test *test)
196d903306aSRobert Watson {
197d903306aSRobert Watson 	int error;
198d903306aSRobert Watson 
199d903306aSRobert Watson 	error = utimes(fpath, NULL);
200d903306aSRobert Watson 	if (asroot && injail)
201d903306aSRobert Watson 		expect("priv_vfs_utimes_fother_null(root, jail)", error, 0,
202d903306aSRobert Watson 		    0);
203d903306aSRobert Watson 	if (asroot && !injail)
204d903306aSRobert Watson 		expect("priv_vfs_utimes_fother_null(root, !jail)", error, 0,
205d903306aSRobert Watson 		    0);
206d903306aSRobert Watson 	if (!asroot && injail)
207d903306aSRobert Watson 		expect("priv_vfs_utimes_fother_null(!root, jail)", error, 0,
208d903306aSRobert Watson 		    0);
209d903306aSRobert Watson 	if (!asroot && !injail)
210d903306aSRobert Watson 		expect("priv_vfs_utimes_fother_null(!root, !jail)", error, 0,
211d903306aSRobert Watson 		    0);
212d903306aSRobert Watson }
213d903306aSRobert Watson 
214d903306aSRobert Watson void
priv_vfs_utimes_cleanup(int asroot,int injail,struct test * test)215d903306aSRobert Watson priv_vfs_utimes_cleanup(int asroot, int injail, struct test *test)
216d903306aSRobert Watson {
217d903306aSRobert Watson 
218d903306aSRobert Watson 	if (fpath_initialized) {
219d903306aSRobert Watson 		(void)unlink(fpath);
220d903306aSRobert Watson 		fpath_initialized = 0;
221d903306aSRobert Watson 	}
222d903306aSRobert Watson }
223