]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/regression/priv/priv_acct.c
This commit was generated by cvs2svn to compensate for changes in r163820,
[FreeBSD/FreeBSD.git] / tools / regression / priv / priv_acct.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  * Test that configuring accounting requires privilege.  First check that
34  * accounting is not in use on the system to prevent disrupting the
35  * accounting service.  Confirm three different state transitions, both as
36  * privileged and non-privileged: disabled to enabled, rotate, and enabled to
37  * disabled.
38  */
39
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <sys/sysctl.h>
43
44 #include <err.h>
45 #include <errno.h>
46 #include <stdlib.h>
47 #include <unistd.h>
48
49 #include "main.h"
50
51 #define SYSCTL_NAME     "kern.acct_configured"
52 #define PATH_TEMPLATE   "/tmp/acct.XXXXXXXXXXX"
53
54 void
55 priv_acct(void)
56 {
57         char fpath1[1024] = PATH_TEMPLATE;
58         char fpath2[1024] = PATH_TEMPLATE;
59         int error, fd, i;
60         size_t len;
61
62         assert_root();
63
64         /*
65          * Check that accounting isn't already configured in the kernel.
66          */
67         len = sizeof(i);
68         if (sysctlbyname(SYSCTL_NAME, &i, &len, NULL, 0) < 0)
69                 err(-1, "sysctlbyname(%s)", SYSCTL_NAME);
70         if (i != 0)
71                 errx(-1, "sysctlbyname(%s) indicates accounting configured",
72                     SYSCTL_NAME);
73
74         /*
75          * Create two temporary files to use as accounting targets.
76          */
77         fd = mkstemp(fpath1);
78         if (fd < 0)
79                 err(-1, "mkstemp");
80         close(fd);
81         fd = mkstemp(fpath2);
82         if (fd < 0) {
83                 warn("mkstemp");
84                 (void)unlink(fpath1);
85                 exit(-1);
86         }
87
88         /*
89          * Change the permissions on the file so that access control on the
90          * file doesn't come into play.
91          */
92         if (chmod(fpath1, 0666) < 0) {
93                 warn("chmod(%s, 0666)", fpath1);
94                 goto out;
95         }
96
97         if (chmod(fpath2, 0666) < 0) {
98                 warn("chmod(%s, 0600)", fpath2);
99                 goto out;
100         }
101
102         /*
103          * Test that privileged can move through entire life cycle.
104          */
105         if (acct(fpath1) < 0) {
106                 warn("acct(NULL -> %s) as root", fpath1);
107                 goto out;
108         }
109
110         if (acct(fpath2) < 0) {
111                 warn("acct(%s -> %s) as root", fpath1, fpath2);
112                 goto out;
113         }
114
115         if (acct(NULL) < 0) {
116                 warn("acct(%s -> NULL) as root", fpath1);
117                 goto out;
118         }
119
120         /*
121          * Testing for unprivileged is a bit more tricky, as expect each step
122          * to fail, so must replay various bits of the setup process as root
123          * so that each step can be tested as !root.
124          */
125         set_euid(UID_OTHER);
126         error = acct(fpath1);
127         if (error == 0) {
128                 warnx("acct(NULL -> %s) succeeded as !root", fpath1);
129                 goto out;
130         }
131         if (errno != EPERM) {
132                 warn("acct(NULL -> %s) wrong errno %d as !root", fpath1,
133                     errno);
134                 goto out;
135         }
136
137         set_euid(UID_ROOT);
138         if (acct(fpath1) < 0) {
139                 err(-1, "acct(NULL -> %s) setup for !root", fpath1);
140                 goto out;
141         }
142
143         set_euid(UID_OTHER);
144         error = acct(fpath2);
145         if (error == 0) {
146                 warnx("acct(%s -> %s) succeeded as !root", fpath1, fpath2);
147                 goto out;
148         }
149         if (errno != EPERM) {
150                 warn("acct(%s -> %s) wrong errno %d as !root", fpath1,
151                     fpath2, errno);
152                 goto out;
153         }
154
155         set_euid(UID_ROOT);
156         if (acct(fpath2) < 0) {
157                 err(-1, "acct(%s -> %s) setup for !root", fpath1, fpath2);
158                 goto out;
159         }
160
161         set_euid(UID_OTHER);
162         error = acct(NULL);
163         if (error == 0) {
164                 warnx("acct(%s -> NULL) succeeded as !root", fpath2);
165                 goto out;
166         }
167         if (errno != EPERM) {
168                 warn("acct(%s -> NULL) wrong errno %d as !root", fpath2,
169                     errno);
170                 goto out;
171         }
172
173 out:
174         (void)seteuid(UID_ROOT);
175         (void)acct(NULL);
176         (void)unlink(fpath1);
177         (void)unlink(fpath2);
178 }