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