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 } 179