]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/regression/priv/priv_vfs_read_write.c
This commit was generated by cvs2svn to compensate for changes in r165743,
[FreeBSD/FreeBSD.git] / tools / regression / priv / priv_vfs_read_write.c
1 /*-
2  * Copyright (c) 2006 nCircle Network Security, Inc.
3  * All rights reserved.
4  *
5  * This software was developed by Robert N. M. Watson for the TrustedBSD
6  * Project under contract to nCircle Network Security, Inc.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
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.
16  *
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.
28  *
29  * $FreeBSD$
30  */
31
32 /*
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.
36  */
37
38 #include <sys/types.h>
39 #include <sys/stat.h>
40
41 #include <err.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47
48 #include "main.h"
49
50 struct test_arguments {
51         int     open_flags;
52         uid_t   proc_uid;
53         gid_t   proc_gid;
54         uid_t   file_uid;
55         gid_t   file_gid;
56 };
57
58 /*
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.
61  */
62 static const char *
63 flags_to_string(int flags)
64 {
65
66         switch (flags) {
67         case O_RDONLY:
68                 return ("O_RDONLY");
69
70         case O_WRONLY:
71                 return ("O_WRONLY");
72
73         default:
74                 return ("unknown");
75         }
76 }
77
78 static void
79 test_perm(struct test_arguments ta, mode_t file_mode, int expected)
80 {
81         uid_t proc_uid, file_uid;
82         gid_t proc_gid, file_gid;
83         int fd, open_flags;
84         char fpath[1024];
85
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;
91
92         setup_file(fpath, file_uid, file_gid, file_mode);
93         set_creds(proc_uid, proc_gid);
94
95         fd = open(fpath, open_flags);
96
97         if (expected == 0) {
98                 if (fd <= 0) {
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,
103                             errno, expected);
104                         restore_creds();
105                         (void)unlink(fpath);
106                         exit(-1);
107                 }
108                 close(fd);
109         } else {
110                 if (fd >= 0) {
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,
115                             expected);
116                         close(fd);
117                         restore_creds();
118                         (void)unlink(fpath);
119                         exit(-1);
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,
125                             errno, expected);
126                         restore_creds();
127                         (void)unlink(fpath);
128                         exit(-1);
129                 }
130         }
131
132         restore_creds();
133         (void)unlink(fpath);
134 }
135
136 static const gid_t gidset[] = { GID_WHEEL };
137
138 static void
139 preamble(void)
140 {
141
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);
146 }
147
148 void
149 priv_vfs_read(void)
150 {
151         struct test_arguments ta;
152
153         preamble();
154
155         ta.open_flags = O_RDONLY;
156
157         /*
158          * Privileged user and file owner.  All tests should pass.
159          */
160         ta.proc_uid = UID_ROOT;
161         ta.proc_gid = GID_WHEEL;
162         ta.file_uid = UID_ROOT;
163         ta.file_gid = GID_WHEEL;
164
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);
173
174         /*
175          * Privileged user and file group.  All tests should pass.
176          */
177         ta.proc_uid = UID_ROOT;
178         ta.proc_gid = GID_WHEEL;
179         ta.file_uid = UID_OWNER;
180         ta.file_gid = GID_WHEEL;
181
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);
190
191         /*
192          * Privileged user and file other.  All tests should pass.
193          */
194         ta.proc_uid = UID_ROOT;
195         ta.proc_gid = GID_WHEEL;
196         ta.file_uid = UID_OWNER;
197         ta.file_gid = GID_OWNER;
198
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);
207
208         /*
209          * Unprivileged user and file owner.  Various DAC failures.
210          */
211         ta.proc_uid = UID_OWNER;
212         ta.proc_gid = GID_OWNER;
213         ta.file_uid = UID_OWNER;
214         ta.file_gid = GID_OWNER;
215
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);
224
225         /*
226          * Unprivileged user and file group.  Various DAC failures.
227          */
228         ta.proc_uid = UID_OTHER;
229         ta.proc_gid = GID_OWNER;
230         ta.file_uid = UID_OWNER;
231         ta.file_gid = GID_OWNER;
232
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);
241
242         /*
243          * Unprivileged user and file other.  Various DAC failures.
244          */
245         ta.proc_uid = UID_OTHER;
246         ta.proc_gid = GID_OTHER;
247         ta.file_uid = UID_OWNER;
248         ta.file_gid = GID_OWNER;
249
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);
258 }
259
260 void
261 priv_vfs_write(void)
262 {
263         struct test_arguments ta;
264
265         preamble();
266
267         ta.open_flags = O_WRONLY;
268
269         /*
270          * Privileged user and file owner.  All tests should pass.
271          */
272         ta.proc_uid = UID_ROOT;
273         ta.proc_gid = GID_WHEEL;
274         ta.file_uid = UID_ROOT;
275         ta.file_gid = GID_WHEEL;
276
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);
285
286         /*
287          * Privileged user and file group.  All tests should pass.
288          */
289         ta.proc_uid = UID_ROOT;
290         ta.proc_gid = GID_WHEEL;
291         ta.file_uid = UID_OWNER;
292         ta.file_gid = GID_WHEEL;
293
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);
302
303         /*
304          * Privileged user and file other.  All tests should pass.
305          */
306         ta.proc_uid = UID_ROOT;
307         ta.proc_gid = GID_WHEEL;
308         ta.file_uid = UID_OWNER;
309         ta.file_gid = GID_OWNER;
310
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);
319
320         /*
321          * Unprivileged user and file owner.  Various DAC failures.
322          */
323         ta.proc_uid = UID_OWNER;
324         ta.proc_gid = GID_OWNER;
325         ta.file_uid = UID_OWNER;
326         ta.file_gid = GID_OWNER;
327
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);
336
337         /*
338          * Unprivileged user and file group.  Various DAC failures.
339          */
340         ta.proc_uid = UID_OTHER;
341         ta.proc_gid = GID_OWNER;
342         ta.file_uid = UID_OWNER;
343         ta.file_gid = GID_OWNER;
344
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);
353
354         /*
355          * Unprivileged user and file other.  Various DAC failures.
356          */
357         ta.proc_uid = UID_OTHER;
358         ta.proc_gid = GID_OTHER;
359         ta.file_uid = UID_OWNER;
360         ta.file_gid = GID_OWNER;
361
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);
370 }