xref: /freebsd/tools/regression/priv/main.c (revision 6007da5f922a96bc983948207c9f26345a8984db)
19fa5f6b4SRobert Watson /*-
29fa5f6b4SRobert Watson  * Copyright (c) 2006 nCircle Network Security, Inc.
3d903306aSRobert Watson  * Copyright (c) 2007 Robert N. M. Watson
49fa5f6b4SRobert Watson  * All rights reserved.
59fa5f6b4SRobert Watson  *
69fa5f6b4SRobert Watson  * This software was developed by Robert N. M. Watson for the TrustedBSD
79fa5f6b4SRobert Watson  * Project under contract to nCircle Network Security, Inc.
89fa5f6b4SRobert Watson  *
99fa5f6b4SRobert Watson  * Redistribution and use in source and binary forms, with or without
109fa5f6b4SRobert Watson  * modification, are permitted provided that the following conditions
119fa5f6b4SRobert Watson  * are met:
129fa5f6b4SRobert Watson  * 1. Redistributions of source code must retain the above copyright
139fa5f6b4SRobert Watson  *    notice, this list of conditions and the following disclaimer.
149fa5f6b4SRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
159fa5f6b4SRobert Watson  *    notice, this list of conditions and the following disclaimer in the
169fa5f6b4SRobert Watson  *    documentation and/or other materials provided with the distribution.
179fa5f6b4SRobert Watson  *
189fa5f6b4SRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
199fa5f6b4SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
209fa5f6b4SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
219fa5f6b4SRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
229fa5f6b4SRobert Watson  * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
239fa5f6b4SRobert Watson  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
249fa5f6b4SRobert Watson  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
259fa5f6b4SRobert Watson  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
269fa5f6b4SRobert Watson  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
279fa5f6b4SRobert Watson  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
289fa5f6b4SRobert Watson  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
299fa5f6b4SRobert Watson  *
309fa5f6b4SRobert Watson  * $FreeBSD$
319fa5f6b4SRobert Watson  */
329fa5f6b4SRobert Watson 
339fa5f6b4SRobert Watson /*
34d903306aSRobert Watson  * Privilege test framework.  Each test is encapsulated on a .c file
35d903306aSRobert Watson  * exporting a function that implements the test.  Each test is run from its
36d903306aSRobert Watson  * own child process, and they are run in sequence one at a time.
379fa5f6b4SRobert Watson  */
389fa5f6b4SRobert Watson 
39d903306aSRobert Watson #include <sys/param.h>
40d903306aSRobert Watson #include <sys/jail.h>
419fa5f6b4SRobert Watson #include <sys/stat.h>
429fa5f6b4SRobert Watson #include <sys/wait.h>
439fa5f6b4SRobert Watson 
44d903306aSRobert Watson #include <netinet/in.h>
45d903306aSRobert Watson 
469fa5f6b4SRobert Watson #include <err.h>
47d903306aSRobert Watson #include <errno.h>
489fa5f6b4SRobert Watson #include <stdio.h>
499fa5f6b4SRobert Watson #include <stdlib.h>
509fa5f6b4SRobert Watson #include <string.h>
519fa5f6b4SRobert Watson #include <unistd.h>
529fa5f6b4SRobert Watson 
539fa5f6b4SRobert Watson #include "main.h"
549fa5f6b4SRobert Watson 
559fa5f6b4SRobert Watson /*
56d903306aSRobert Watson  * Registration table of privilege tests.  Each test registers a name, a test
57d903306aSRobert Watson  * function, and a cleanup function to run after the test has completed,
58d903306aSRobert Watson  * regardless of success/failure.
599fa5f6b4SRobert Watson  */
60d903306aSRobert Watson static struct test tests[] = {
61d903306aSRobert Watson 	{ "priv_acct_enable", priv_acct_setup, priv_acct_enable,
62d903306aSRobert Watson 	    priv_acct_cleanup },
63d903306aSRobert Watson 
64d903306aSRobert Watson 	{ "priv_acct_disable", priv_acct_setup, priv_acct_disable,
65d903306aSRobert Watson 	    priv_acct_cleanup },
66d903306aSRobert Watson 
67d903306aSRobert Watson 	{ "priv_acct_rotate", priv_acct_setup, priv_acct_rotate,
68d903306aSRobert Watson 	    priv_acct_cleanup },
69d903306aSRobert Watson 
70d903306aSRobert Watson 	{ "priv_acct_noopdisable", priv_acct_setup, priv_acct_noopdisable,
71d903306aSRobert Watson 	    priv_acct_cleanup },
72d903306aSRobert Watson 
73d903306aSRobert Watson 	{ "priv_adjtime_set", priv_adjtime_setup, priv_adjtime_set,
74d903306aSRobert Watson 	    priv_adjtime_cleanup },
75d903306aSRobert Watson 
76d903306aSRobert Watson 	{ "priv_audit_submit", priv_audit_submit_setup, priv_audit_submit,
77d903306aSRobert Watson 	    priv_audit_submit_cleanup },
78d903306aSRobert Watson 
79d903306aSRobert Watson 	{ "priv_audit_control", priv_audit_control_setup, priv_audit_control,
80d903306aSRobert Watson 	    priv_audit_control_cleanup },
81d903306aSRobert Watson 
82d903306aSRobert Watson 	{ "priv_audit_getaudit", priv_audit_getaudit_setup,
83d903306aSRobert Watson 	    priv_audit_getaudit, priv_audit_getaudit_cleanup },
84d903306aSRobert Watson 
85d903306aSRobert Watson 	{ "priv_audit_getaudit_addr", priv_audit_getaudit_setup,
86d903306aSRobert Watson 	    priv_audit_getaudit_addr, priv_audit_getaudit_cleanup },
87d903306aSRobert Watson 
88d903306aSRobert Watson 	{ "priv_audit_setaudit", priv_audit_setaudit_setup,
89d903306aSRobert Watson 	    priv_audit_setaudit, priv_audit_setaudit_cleanup },
90d903306aSRobert Watson 
91d903306aSRobert Watson 	{ "priv_audit_setaudit_addr", priv_audit_setaudit_setup,
92d903306aSRobert Watson 	    priv_audit_setaudit_addr, priv_audit_setaudit_cleanup },
93d903306aSRobert Watson 
94d903306aSRobert Watson 	{ "priv_clock_settime", priv_clock_settime_setup, priv_clock_settime,
95d903306aSRobert Watson 	    priv_clock_settime_cleanup },
96d903306aSRobert Watson 
97d903306aSRobert Watson 	{ "priv_cred_setuid", priv_cred_setup, priv_cred_setuid,
98d903306aSRobert Watson 	    priv_cred_cleanup },
99d903306aSRobert Watson 
100d903306aSRobert Watson 	{ "priv_cred_seteuid", priv_cred_setup, priv_cred_seteuid,
101d903306aSRobert Watson 	    priv_cred_cleanup },
102d903306aSRobert Watson 
103d903306aSRobert Watson 	{ "priv_cred_setgid", priv_cred_setup, priv_cred_setgid,
104d903306aSRobert Watson 	    priv_cred_cleanup },
105d903306aSRobert Watson 
106d903306aSRobert Watson 	{ "priv_cred_setegid", priv_cred_setup, priv_cred_setegid,
107d903306aSRobert Watson 	    priv_cred_cleanup },
108d903306aSRobert Watson 
109d903306aSRobert Watson 	{ "priv_cred_setgroups", priv_cred_setup, priv_cred_setgroups,
110d903306aSRobert Watson 	    priv_cred_cleanup },
111d903306aSRobert Watson 
112d903306aSRobert Watson 	{ "priv_cred_setreuid", priv_cred_setup, priv_cred_setreuid,
113d903306aSRobert Watson 	    priv_cred_cleanup },
114d903306aSRobert Watson 
115d903306aSRobert Watson 	{ "priv_cred_setregid", priv_cred_setup, priv_cred_setregid,
116d903306aSRobert Watson 	    priv_cred_cleanup },
117d903306aSRobert Watson 
118d903306aSRobert Watson 	{ "priv_cred_setresuid", priv_cred_setup, priv_cred_setresuid,
119d903306aSRobert Watson 	    priv_cred_cleanup },
120d903306aSRobert Watson 
121d903306aSRobert Watson 	{ "priv_cred_setresgid", priv_cred_setup, priv_cred_setresgid,
122d903306aSRobert Watson 	    priv_cred_cleanup },
123d903306aSRobert Watson 
124d903306aSRobert Watson 	{ "priv_io", priv_io_setup, priv_io, priv_io_cleanup },
125d903306aSRobert Watson 
126d903306aSRobert Watson 	{ "priv_kenv_set", priv_kenv_set_setup, priv_kenv_set,
127d903306aSRobert Watson 	    priv_kenv_set_cleanup },
128d903306aSRobert Watson 
129d903306aSRobert Watson 	{ "priv_kenv_unset", priv_kenv_unset_setup, priv_kenv_unset,
130d903306aSRobert Watson 	    priv_kenv_unset_cleanup },
131d903306aSRobert Watson 
132d903306aSRobert Watson 	{ "priv_msgbuf_privonly", priv_msgbuf_privonly_setup,
133d903306aSRobert Watson 	    priv_msgbuf_privonly, priv_msgbuf_cleanup },
134d903306aSRobert Watson 
135d903306aSRobert Watson 	{ "priv_msgbuf_unprivok", priv_msgbuf_unprivok_setup,
136d903306aSRobert Watson 	   priv_msgbuf_unprivok, priv_msgbuf_cleanup },
137d903306aSRobert Watson 
1386007da5fSBjoern A. Zeeb 	{ "priv_netinet_ipsec_pfkey", priv_netinet_ipsec_pfkey_setup,
1396007da5fSBjoern A. Zeeb 	    priv_netinet_ipsec_pfkey, priv_netinet_ipsec_pfkey_cleanup },
1406007da5fSBjoern A. Zeeb 
141d903306aSRobert Watson 	{ "priv_netinet_raw", priv_netinet_raw_setup, priv_netinet_raw,
142d903306aSRobert Watson 	    priv_netinet_raw_cleanup },
143d903306aSRobert Watson 
144d903306aSRobert Watson 	{ "priv_proc_setlogin", priv_proc_setlogin_setup, priv_proc_setlogin,
145d903306aSRobert Watson 	    priv_proc_setlogin_cleanup },
146d903306aSRobert Watson 
147d903306aSRobert Watson 	{ "priv_proc_setrlimit_raisemax", priv_proc_setrlimit_setup,
148d903306aSRobert Watson 	    priv_proc_setrlimit_raisemax, priv_proc_setrlimit_cleanup },
149d903306aSRobert Watson 
150d903306aSRobert Watson 	{ "priv_proc_setrlimit_raisecur", priv_proc_setrlimit_setup,
151d903306aSRobert Watson 	    priv_proc_setrlimit_raisecur, priv_proc_setrlimit_cleanup },
152d903306aSRobert Watson 
153d903306aSRobert Watson 	{ "priv_proc_setrlimit_raisecur_nopriv", priv_proc_setrlimit_setup,
154d903306aSRobert Watson 	    priv_proc_setrlimit_raisecur_nopriv,
155d903306aSRobert Watson 	    priv_proc_setrlimit_cleanup },
156d903306aSRobert Watson 
157d903306aSRobert Watson 	{ "priv_sched_rtprio_curproc_normal", priv_sched_rtprio_setup,
158d903306aSRobert Watson 	    priv_sched_rtprio_curproc_normal, priv_sched_rtprio_cleanup },
159d903306aSRobert Watson 
160d903306aSRobert Watson 	{ "priv_sched_rtprio_curproc_idle", priv_sched_rtprio_setup,
161d903306aSRobert Watson 	    priv_sched_rtprio_curproc_idle, priv_sched_rtprio_cleanup },
162d903306aSRobert Watson 
163d903306aSRobert Watson 	{ "priv_sched_rtprio_curproc_realtime", priv_sched_rtprio_setup,
164d903306aSRobert Watson 	    priv_sched_rtprio_curproc_realtime, priv_sched_rtprio_cleanup },
165d903306aSRobert Watson 
166d903306aSRobert Watson 	{ "priv_sched_rtprio_myproc_normal", priv_sched_rtprio_setup,
167d903306aSRobert Watson 	    priv_sched_rtprio_myproc_normal, priv_sched_rtprio_cleanup },
168d903306aSRobert Watson 
169d903306aSRobert Watson 	{ "priv_sched_rtprio_myproc_idle", priv_sched_rtprio_setup,
170d903306aSRobert Watson 	    priv_sched_rtprio_myproc_idle, priv_sched_rtprio_cleanup },
171d903306aSRobert Watson 
172d903306aSRobert Watson 	{ "priv_sched_rtprio_myproc_realtime", priv_sched_rtprio_setup,
173d903306aSRobert Watson 	    priv_sched_rtprio_myproc_realtime, priv_sched_rtprio_cleanup },
174d903306aSRobert Watson 
175d903306aSRobert Watson 	{ "priv_sched_rtprio_aproc_normal", priv_sched_rtprio_setup,
176d903306aSRobert Watson 	    priv_sched_rtprio_aproc_normal, priv_sched_rtprio_cleanup },
177d903306aSRobert Watson 
178d903306aSRobert Watson 	{ "priv_sched_rtprio_aproc_idle", priv_sched_rtprio_setup,
179d903306aSRobert Watson 	    priv_sched_rtprio_aproc_idle, priv_sched_rtprio_cleanup },
180d903306aSRobert Watson 
181d903306aSRobert Watson 	{ "priv_sched_rtprio_aproc_realtime", priv_sched_rtprio_setup,
182d903306aSRobert Watson 	    priv_sched_rtprio_aproc_realtime, priv_sched_rtprio_cleanup },
183d903306aSRobert Watson 
184d903306aSRobert Watson 	{ "priv_sched_setpriority_curproc", priv_sched_setpriority_setup,
185d903306aSRobert Watson 	    priv_sched_setpriority_curproc, priv_sched_setpriority_cleanup },
186d903306aSRobert Watson 
187d903306aSRobert Watson 	{ "priv_sched_setpriority_myproc", priv_sched_setpriority_setup,
188d903306aSRobert Watson 	    priv_sched_setpriority_myproc, priv_sched_setpriority_cleanup },
189d903306aSRobert Watson 
190d903306aSRobert Watson 	{ "priv_sched_setpriority_aproc", priv_sched_setpriority_setup,
191d903306aSRobert Watson 	    priv_sched_setpriority_aproc, priv_sched_setpriority_cleanup },
192d903306aSRobert Watson 
193d903306aSRobert Watson 	{ "priv_settimeofday", priv_settimeofday_setup, priv_settimeofday,
194d903306aSRobert Watson 	    priv_settimeofday_cleanup },
195d903306aSRobert Watson 
196d903306aSRobert Watson 	{ "priv_sysctl_write", priv_sysctl_write_setup, priv_sysctl_write,
197d903306aSRobert Watson 	    priv_sysctl_write_cleanup },
198d903306aSRobert Watson 
199d903306aSRobert Watson 	{ "priv_sysctl_writejail", priv_sysctl_write_setup,
200d903306aSRobert Watson 	    priv_sysctl_writejail, priv_sysctl_write_cleanup },
201d903306aSRobert Watson 
202d903306aSRobert Watson 	{ "priv_vfs_chflags_froot_uflags", priv_vfs_chflags_froot_setup,
203d903306aSRobert Watson 	    priv_vfs_chflags_froot_uflags, priv_vfs_chflags_cleanup },
204d903306aSRobert Watson 
205d903306aSRobert Watson 	{ "priv_vfs_chflags_froot_sflags", priv_vfs_chflags_froot_setup,
206d903306aSRobert Watson 	    priv_vfs_chflags_froot_sflags, priv_vfs_chflags_cleanup },
207d903306aSRobert Watson 
208d903306aSRobert Watson 	{ "priv_vfs_chflags_fowner_uflags", priv_vfs_chflags_fowner_setup,
209d903306aSRobert Watson 	    priv_vfs_chflags_fowner_uflags, priv_vfs_chflags_cleanup },
210d903306aSRobert Watson 
211d903306aSRobert Watson 	{ "priv_vfs_chflags_fowner_sflags", priv_vfs_chflags_fowner_setup,
212d903306aSRobert Watson 	    priv_vfs_chflags_fowner_sflags, priv_vfs_chflags_cleanup },
213d903306aSRobert Watson 
214d903306aSRobert Watson 	{ "priv_vfs_chflags_fother_uflags", priv_vfs_chflags_fother_setup,
215d903306aSRobert Watson 	    priv_vfs_chflags_fother_uflags, priv_vfs_chflags_cleanup },
216d903306aSRobert Watson 
217d903306aSRobert Watson 	{ "priv_vfs_chflags_fother_sflags", priv_vfs_chflags_fother_setup,
218d903306aSRobert Watson 	    priv_vfs_chflags_fother_sflags, priv_vfs_chflags_cleanup },
219d903306aSRobert Watson 
220d903306aSRobert Watson 	{ "priv_vfs_chmod_froot", priv_vfs_chmod_froot_setup,
221d903306aSRobert Watson 	     priv_vfs_chmod_froot, priv_vfs_chmod_cleanup },
222d903306aSRobert Watson 
223d903306aSRobert Watson 	{ "priv_vfs_chmod_fowner", priv_vfs_chmod_fowner_setup,
224d903306aSRobert Watson 	     priv_vfs_chmod_fowner, priv_vfs_chmod_cleanup },
225d903306aSRobert Watson 
226d903306aSRobert Watson 	{ "priv_vfs_chmod_fother", priv_vfs_chmod_fother_setup,
227d903306aSRobert Watson 	     priv_vfs_chmod_fother, priv_vfs_chmod_cleanup },
228d903306aSRobert Watson 
229d903306aSRobert Watson 	{ "priv_vfs_chown_uid", priv_vfs_chown_uid_setup, priv_vfs_chown_uid,
230d903306aSRobert Watson 	    priv_vfs_chown_cleanup },
231d903306aSRobert Watson 
232d903306aSRobert Watson 	{ "priv_vfs_chown_mygid", priv_vfs_chown_mygid_setup,
233d903306aSRobert Watson 	    priv_vfs_chown_mygid, priv_vfs_chown_cleanup },
234d903306aSRobert Watson 
235d903306aSRobert Watson 	{ "priv_vfs_chown_othergid", priv_vfs_chown_othergid_setup,
236d903306aSRobert Watson 	    priv_vfs_chown_othergid, priv_vfs_chown_cleanup },
237d903306aSRobert Watson 
238d903306aSRobert Watson 	{ "priv_vfs_chroot", priv_vfs_chroot_setup, priv_vfs_chroot,
239d903306aSRobert Watson 	    priv_vfs_chroot_cleanup },
240d903306aSRobert Watson 
241d903306aSRobert Watson 	{ "priv_vfs_clearsugid_chgrp", priv_vfs_clearsugid_setup,
242d903306aSRobert Watson 	    priv_vfs_clearsugid_chgrp, priv_vfs_clearsugid_cleanup },
243d903306aSRobert Watson 
244d903306aSRobert Watson 	{ "priv_vfs_clearsugid_extattr", priv_vfs_clearsugid_setup,
245d903306aSRobert Watson 	    priv_vfs_clearsugid_extattr, priv_vfs_clearsugid_cleanup },
246d903306aSRobert Watson 
247d903306aSRobert Watson 	{ "priv_vfs_clearsugid_write", priv_vfs_clearsugid_setup,
248d903306aSRobert Watson 	    priv_vfs_clearsugid_write, priv_vfs_clearsugid_cleanup },
249d903306aSRobert Watson 
250d903306aSRobert Watson 	{ "priv_vfs_extattr_system", priv_vfs_extattr_system_setup,
251d903306aSRobert Watson 	    priv_vfs_extattr_system, priv_vfs_extattr_system_cleanup },
252d903306aSRobert Watson 
253d903306aSRobert Watson 	{ "priv_vfs_fhopen", priv_vfs_fhopen_setup, priv_vfs_fhopen,
254d903306aSRobert Watson 	    priv_vfs_fhopen_cleanup },
255d903306aSRobert Watson 
256d903306aSRobert Watson 	{ "priv_vfs_fhstat", priv_vfs_fhstat_setup, priv_vfs_fhstat,
257d903306aSRobert Watson 	    priv_vfs_fhstat_cleanup },
258d903306aSRobert Watson 
259d903306aSRobert Watson 	{ "priv_vfs_fhstatfs", priv_vfs_fhstatfs_setup, priv_vfs_fhstatfs,
260d903306aSRobert Watson 	    priv_vfs_fhstatfs_cleanup },
261d903306aSRobert Watson 
262d903306aSRobert Watson 	{ "priv_vfs_generation", priv_vfs_generation_setup,
263d903306aSRobert Watson 	    priv_vfs_generation, priv_vfs_generation_cleanup },
264d903306aSRobert Watson 
265d903306aSRobert Watson 	{ "priv_vfs_getfh", priv_vfs_getfh_setup, priv_vfs_getfh,
266d903306aSRobert Watson 	    priv_vfs_getfh_cleanup },
267d903306aSRobert Watson 
268d903306aSRobert Watson 	{ "priv_vfs_readwrite_fowner", priv_vfs_readwrite_fowner_setup,
269d903306aSRobert Watson 	    priv_vfs_readwrite_fowner, priv_vfs_readwrite_cleanup },
270d903306aSRobert Watson 
271d903306aSRobert Watson 	{ "priv_vfs_readwrite_fgroup", priv_vfs_readwrite_fgroup_setup,
272d903306aSRobert Watson 	    priv_vfs_readwrite_fgroup, priv_vfs_readwrite_cleanup },
273d903306aSRobert Watson 
274d903306aSRobert Watson 	{ "priv_vfs_readwrite_fother", priv_vfs_readwrite_fother_setup,
275d903306aSRobert Watson 	    priv_vfs_readwrite_fother, priv_vfs_readwrite_cleanup },
276d903306aSRobert Watson 
277d903306aSRobert Watson 	{ "priv_vfs_setgid_fowner", priv_vfs_setgid_fowner_setup,
278d903306aSRobert Watson 	    priv_vfs_setgid_fowner, priv_vfs_setgid_cleanup },
279d903306aSRobert Watson 
280d903306aSRobert Watson 	{ "priv_vfs_setgid_fother", priv_vfs_setgid_fother_setup,
281d903306aSRobert Watson 	    priv_vfs_setgid_fother, priv_vfs_setgid_cleanup },
282d903306aSRobert Watson 
283d903306aSRobert Watson 	{ "priv_vfs_stickyfile_dir_fowner",
284d903306aSRobert Watson 	    priv_vfs_stickyfile_dir_fowner_setup,
285d903306aSRobert Watson 	    priv_vfs_stickyfile_dir_fowner,
286d903306aSRobert Watson 	    priv_vfs_stickyfile_dir_cleanup },
287d903306aSRobert Watson 
288d903306aSRobert Watson 	{ "priv_vfs_stickyfile_dir_fother",
289d903306aSRobert Watson 	    priv_vfs_stickyfile_dir_fother_setup,
290d903306aSRobert Watson 	    priv_vfs_stickyfile_dir_fother,
291d903306aSRobert Watson 	    priv_vfs_stickyfile_dir_cleanup },
292d903306aSRobert Watson 
293d903306aSRobert Watson 	{ "priv_vfs_stickyfile_file_fowner",
294d903306aSRobert Watson 	    priv_vfs_stickyfile_file_fowner_setup,
295d903306aSRobert Watson 	    priv_vfs_stickyfile_file_fowner,
296d903306aSRobert Watson 	    priv_vfs_stickyfile_file_cleanup },
297d903306aSRobert Watson 
298d903306aSRobert Watson 	{ "priv_vfs_stickyfile_file_fother",
299d903306aSRobert Watson 	    priv_vfs_stickyfile_file_fother_setup,
300d903306aSRobert Watson 	    priv_vfs_stickyfile_file_fother,
301d903306aSRobert Watson 	    priv_vfs_stickyfile_file_cleanup },
302d903306aSRobert Watson 
303d903306aSRobert Watson 	{ "priv_vfs_utimes_froot", priv_vfs_utimes_froot_setup,
304d903306aSRobert Watson 	    priv_vfs_utimes_froot, priv_vfs_utimes_cleanup },
305d903306aSRobert Watson 
306d903306aSRobert Watson 	{ "priv_vfs_utimes_froot_null", priv_vfs_utimes_froot_setup,
307d903306aSRobert Watson 	    priv_vfs_utimes_froot_null, priv_vfs_utimes_cleanup },
308d903306aSRobert Watson 
309d903306aSRobert Watson 	{ "priv_vfs_utimes_fowner", priv_vfs_utimes_fowner_setup,
310d903306aSRobert Watson 	    priv_vfs_utimes_fowner, priv_vfs_utimes_cleanup },
311d903306aSRobert Watson 
312d903306aSRobert Watson 	{ "priv_vfs_utimes_fowner_null", priv_vfs_utimes_fowner_setup,
313d903306aSRobert Watson 	    priv_vfs_utimes_fowner_null, priv_vfs_utimes_cleanup },
314d903306aSRobert Watson 
315d903306aSRobert Watson 	{ "priv_vfs_utimes_fother", priv_vfs_utimes_fother_setup,
316d903306aSRobert Watson 	    priv_vfs_utimes_fother, priv_vfs_utimes_cleanup },
317d903306aSRobert Watson 
318d903306aSRobert Watson 	{ "priv_vfs_utimes_fother_null", priv_vfs_utimes_fother_setup,
319d903306aSRobert Watson 	    priv_vfs_utimes_fother_null, priv_vfs_utimes_cleanup },
320d903306aSRobert Watson 
321d903306aSRobert Watson 	{ "priv_vm_madv_protect", priv_vm_madv_protect_setup,
322d903306aSRobert Watson 	    priv_vm_madv_protect, priv_vm_madv_protect_cleanup },
323d903306aSRobert Watson 
324d903306aSRobert Watson 	{ "priv_vm_mlock", priv_vm_mlock_setup, priv_vm_mlock,
325d903306aSRobert Watson 	    priv_vm_mlock_cleanup },
326d903306aSRobert Watson 
327d903306aSRobert Watson 	{ "priv_vm_munlock", priv_vm_munlock_setup, priv_vm_munlock,
328d903306aSRobert Watson 	    priv_vm_munlock_cleanup },
329d903306aSRobert Watson 
330d903306aSRobert Watson };
331d903306aSRobert Watson static int tests_count = sizeof(tests) / sizeof(struct test);
332d903306aSRobert Watson 
3339fa5f6b4SRobert Watson void
334d903306aSRobert Watson expect(const char *test, int error, int expected_error, int expected_errno)
3359fa5f6b4SRobert Watson {
3369fa5f6b4SRobert Watson 
337d903306aSRobert Watson 	if (error == 0) {
338d903306aSRobert Watson 		if (expected_error != 0)
339d903306aSRobert Watson 			warnx("%s: returned 0", test);
340d903306aSRobert Watson 	} else {
341d903306aSRobert Watson 		if (expected_error == 0)
342d903306aSRobert Watson 			warn("%s: returned (%d, %d)", test, error, errno);
343d903306aSRobert Watson 		else if (expected_errno != errno)
344d903306aSRobert Watson 			warn("%s: returned (%d, %d)", test, error, errno);
345d903306aSRobert Watson 	}
3469fa5f6b4SRobert Watson }
3479fa5f6b4SRobert Watson 
3489fa5f6b4SRobert Watson void
349d903306aSRobert Watson setup_dir(const char *test, char *dpathp, uid_t uid, gid_t gid, mode_t mode)
350d903306aSRobert Watson {
351d903306aSRobert Watson 
352d903306aSRobert Watson 	strcpy(dpathp, "/tmp/priv.XXXXXXXXXXX");
353d903306aSRobert Watson 	if (mkdtemp(dpathp) == NULL)
354d903306aSRobert Watson 		err(-1, "test %s: mkdtemp", test);
355d903306aSRobert Watson 
356d903306aSRobert Watson 	if (chown(dpathp, uid, gid) < 0)
357d903306aSRobert Watson 		err(-1, "test %s: chown(%s, %d, %d)", test, dpathp, uid,
358d903306aSRobert Watson 		    gid);
359d903306aSRobert Watson 
360d903306aSRobert Watson 	if (chmod(dpathp, mode) < 0)
361d903306aSRobert Watson 		err(-1, "test %s: chmod(%s, 0%o)", test, dpathp, mode);
362d903306aSRobert Watson }
363d903306aSRobert Watson 
364d903306aSRobert Watson void
365d903306aSRobert Watson setup_file(const char *test, char *fpathp, uid_t uid, gid_t gid, mode_t mode)
3669fa5f6b4SRobert Watson {
3679fa5f6b4SRobert Watson 	int fd;
3689fa5f6b4SRobert Watson 
3699fa5f6b4SRobert Watson 	strcpy(fpathp, "/tmp/priv.XXXXXXXXXXX");
3709fa5f6b4SRobert Watson 	fd = mkstemp(fpathp);
3719fa5f6b4SRobert Watson 	if (fd < 0)
372d903306aSRobert Watson 		err(-1, "test %s: mkstemp", test);
3739fa5f6b4SRobert Watson 
3749fa5f6b4SRobert Watson 	if (fchown(fd, uid, gid) < 0)
375d903306aSRobert Watson 		err(-1, "test %s: fchown(%s, %d, %d)", test, fpathp, uid,
376d903306aSRobert Watson 		    gid);
3779fa5f6b4SRobert Watson 
3789fa5f6b4SRobert Watson 	if (fchmod(fd, mode) < 0)
379d903306aSRobert Watson 		err(-1, "test %s: chmod(%s, 0%o)", test, fpathp, mode);
3809fa5f6b4SRobert Watson 
3819fa5f6b4SRobert Watson 	close(fd);
3829fa5f6b4SRobert Watson }
3839fa5f6b4SRobert Watson 
3849fa5f6b4SRobert Watson /*
385d903306aSRobert Watson  * Irrevocably set credentials to specific uid and gid.
3869fa5f6b4SRobert Watson  */
387d903306aSRobert Watson static void
388d903306aSRobert Watson set_creds(const char *test, uid_t uid, gid_t gid)
3899fa5f6b4SRobert Watson {
390d903306aSRobert Watson 	gid_t gids[1] = { gid };
3919fa5f6b4SRobert Watson 
392d903306aSRobert Watson 	if (setgid(gid) < 0)
393d903306aSRobert Watson 		err(-1, "test %s: setegid(%d)", test, gid);
394d903306aSRobert Watson 	if (setgroups(sizeof(gids)/sizeof(gid_t), gids) < 0)
395d903306aSRobert Watson 		err(-1, "test %s: setgroups(%d)", test, gid);
396d903306aSRobert Watson 	if (setuid(uid) < 0)
397d903306aSRobert Watson 		err(-1, "test %s: seteuid(%d)", test, uid);
3989fa5f6b4SRobert Watson }
3999fa5f6b4SRobert Watson 
400d903306aSRobert Watson static void
401d903306aSRobert Watson enter_jail(const char *test)
4029fa5f6b4SRobert Watson {
403d903306aSRobert Watson 	struct jail j;
4049fa5f6b4SRobert Watson 
405d903306aSRobert Watson 	bzero(&j, sizeof(j));
406d903306aSRobert Watson 	j.version = 0;
407d903306aSRobert Watson 	j.path = "/";
408d903306aSRobert Watson 	j.hostname = "test";
409d903306aSRobert Watson 	j.ip_number = htonl(INADDR_LOOPBACK);
410d903306aSRobert Watson 	if (jail(&j) < 0)
411d903306aSRobert Watson 		err(-1, "test %s: jail", test);
4129fa5f6b4SRobert Watson }
4139fa5f6b4SRobert Watson 
414d903306aSRobert Watson static void
415d903306aSRobert Watson run_child(struct test *test, int asroot, int injail)
4169fa5f6b4SRobert Watson {
4179fa5f6b4SRobert Watson 
418d903306aSRobert Watson 	setprogname(test->t_name);
419d903306aSRobert Watson 	if (injail)
420d903306aSRobert Watson 		enter_jail(test->t_name);
421d903306aSRobert Watson 	if (!asroot)
422d903306aSRobert Watson 		set_creds(test->t_name, UID_OWNER, GID_OWNER);
423d903306aSRobert Watson 	test->t_test_func(asroot, injail, test);
4249fa5f6b4SRobert Watson }
4259fa5f6b4SRobert Watson 
4269fa5f6b4SRobert Watson /*
427d903306aSRobert Watson  * Run a test in a particular credential context -- always call the setup and
428d903306aSRobert Watson  * cleanup routines; if setup succeeds, also run the test.  Test cleanup must
429d903306aSRobert Watson  * handle cases where the setup has failed, so may need to maintain their own
430d903306aSRobert Watson  * state in order to know what needs cleaning up (such as whether temporary
431d903306aSRobert Watson  * files were created).
4329fa5f6b4SRobert Watson  */
4339fa5f6b4SRobert Watson static void
434d903306aSRobert Watson run(struct test *test, int asroot, int injail)
4359fa5f6b4SRobert Watson {
4369fa5f6b4SRobert Watson 	pid_t childpid, pid;
4379fa5f6b4SRobert Watson 
438d903306aSRobert Watson 	if (test->t_setup_func != NULL) {
439d903306aSRobert Watson 		if ((test->t_setup_func)(asroot, injail, test) != 0) {
440d903306aSRobert Watson 			warnx("run(%s, %d, %d) setup failed", test->t_name,
441d903306aSRobert Watson 			    asroot, injail);
442d903306aSRobert Watson 			goto cleanup;
443d903306aSRobert Watson 		}
444d903306aSRobert Watson 	}
4459fa5f6b4SRobert Watson 	fflush(stdout);
4469fa5f6b4SRobert Watson 	fflush(stderr);
4479fa5f6b4SRobert Watson 	childpid = fork();
448d903306aSRobert Watson 	if (childpid == -1) {
449d903306aSRobert Watson 		warn("run(%s, %d, %d) fork failed", test->t_name, asroot,
450d903306aSRobert Watson 		    injail);
451d903306aSRobert Watson 		goto cleanup;
452d903306aSRobert Watson 	}
4539fa5f6b4SRobert Watson 	if (childpid == 0) {
454d903306aSRobert Watson 		run_child(test, asroot, injail);
4559fa5f6b4SRobert Watson 		fflush(stdout);
4569fa5f6b4SRobert Watson 		fflush(stderr);
4579fa5f6b4SRobert Watson 		exit(0);
4589fa5f6b4SRobert Watson 	} else {
4599fa5f6b4SRobert Watson 		while (1) {
4609fa5f6b4SRobert Watson 			pid = waitpid(childpid, NULL, 0);
4619fa5f6b4SRobert Watson 			if (pid == -1)
462d903306aSRobert Watson 				warn("test: waitpid %s", test->t_name);
4639fa5f6b4SRobert Watson 			if (pid == childpid)
4649fa5f6b4SRobert Watson 				break;
4659fa5f6b4SRobert Watson 		}
4669fa5f6b4SRobert Watson 	}
4679fa5f6b4SRobert Watson 	fflush(stdout);
4689fa5f6b4SRobert Watson 	fflush(stderr);
469d903306aSRobert Watson cleanup:
470d903306aSRobert Watson 	if (test->t_cleanup_func != NULL)
471d903306aSRobert Watson 		test->t_cleanup_func(asroot, injail, test);
4729fa5f6b4SRobert Watson }
4739fa5f6b4SRobert Watson 
4749fa5f6b4SRobert Watson int
4759fa5f6b4SRobert Watson main(int argc, char *argv[])
4769fa5f6b4SRobert Watson {
477d903306aSRobert Watson 	int i;
4789fa5f6b4SRobert Watson 
479d903306aSRobert Watson 	/*
480d903306aSRobert Watson 	 * This test suite will need to become quite a bit more enlightened
481d903306aSRobert Watson 	 * if the notion of privilege is truly separated from root, as tests
482d903306aSRobert Watson 	 * make assumptions about when privilege will be present.  In
483d903306aSRobert Watson 	 * particular, VFS-related tests need to manage uids in order to
484d903306aSRobert Watson 	 * force the use of privilege, and will likely need checking.
485d903306aSRobert Watson 	 */
486d903306aSRobert Watson 	if (getuid() != 0 && geteuid() != 0)
487d903306aSRobert Watson 		errx(-1, "priv: must be run as root");
4889fa5f6b4SRobert Watson 
489d903306aSRobert Watson 	/*
490d903306aSRobert Watson 	 * Run each test four times, varying whether the process is running
491d903306aSRobert Watson 	 * as root and in jail in order to test all possible combinations.
492d903306aSRobert Watson 	 */
493d903306aSRobert Watson 	for (i = 0; i < tests_count; i++) {
494d903306aSRobert Watson 		run(&tests[i], 0, 0);
495d903306aSRobert Watson 		run(&tests[i], 0, 1);
496d903306aSRobert Watson 		run(&tests[i], 1, 0);
497d903306aSRobert Watson 		run(&tests[i], 1, 1);
498d903306aSRobert Watson 	}
4999fa5f6b4SRobert Watson 	return (0);
5009fa5f6b4SRobert Watson }
501