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 31 /* 32 * Test NULL and non-NULL tv arguments to utimes() -- if NULL, then it is 33 * allowed without privilege if the owner or if write access is held. If 34 * non-NULL, privilege is required even if writable. 35 */ 36 37 #include <sys/types.h> 38 #include <sys/stat.h> 39 40 #include <err.h> 41 #include <errno.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <unistd.h> 45 46 #include "main.h" 47 48 static char fpath[1024]; 49 static int fpath_initialized; 50 51 int 52 priv_vfs_utimes_froot_setup(int asroot, int injail, struct test *test) 53 { 54 55 setup_file("priv_vfs_utimes_froot_setup: fpath", fpath, 56 UID_ROOT, GID_WHEEL, 0600); 57 fpath_initialized = 1; 58 return (0); 59 } 60 61 int 62 priv_vfs_utimes_fowner_setup(int asroot, int injail, struct test *test) 63 { 64 65 setup_file("priv_vfs_utimes_fowner_setup: fpath", fpath, 66 UID_OWNER, GID_OWNER, 0600); 67 fpath_initialized = 1; 68 return (0); 69 } 70 71 int 72 priv_vfs_utimes_fother_setup(int asroot, int injail, struct test *test) 73 { 74 75 /* 76 * In the 'other' case, we make the file writable by the test user so 77 * we can evaluate the difference between setting the time to NULL, 78 * which is possible as a writer, and non-NULL, which requires 79 * ownership. 80 */ 81 setup_file("priv_vfs_utimes_fother_setup: fpath", fpath, 82 UID_OTHER, GID_OTHER, 0666); 83 fpath_initialized = 1; 84 return (0); 85 } 86 87 void 88 priv_vfs_utimes_froot(int asroot, int injail, struct test *test) 89 { 90 struct timeval tv[2]; 91 int error; 92 93 tv[0].tv_sec = 0; 94 tv[0].tv_usec = 0; 95 tv[1].tv_sec = 0; 96 tv[1].tv_usec = 0; 97 error = utimes(fpath, tv); 98 if (asroot && injail) 99 expect("priv_vfs_utimes_froot(root, jail)", error, 0, 0); 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, -1, 104 EPERM); 105 if (!asroot && !injail) 106 expect("priv_vfs_utimes_froot(!root, !jail)", error, -1, 107 EPERM); 108 } 109 110 void 111 priv_vfs_utimes_froot_null(int asroot, int injail, struct test *test) 112 { 113 int error; 114 115 error = utimes(fpath, NULL); 116 if (asroot && injail) 117 expect("priv_vfs_utimes_froot_null(root, jail)", error, 0, 118 0); 119 if (asroot && !injail) 120 expect("priv_vfs_utimes_froot_null(root, !jail)", error, 0, 121 0); 122 if (!asroot && injail) 123 expect("priv_vfs_utimes_froot_null(!root, jail)", error, -1, 124 EACCES); 125 if (!asroot && !injail) 126 expect("priv_vfs_utimes_froot_null(!root, !jail)", error, -1, 127 EACCES); 128 } 129 130 void 131 priv_vfs_utimes_fowner(int asroot, int injail, struct test *test) 132 { 133 struct timeval tv[2]; 134 int error; 135 136 tv[0].tv_sec = 0; 137 tv[0].tv_usec = 0; 138 tv[1].tv_sec = 0; 139 tv[1].tv_usec = 0; 140 error = utimes(fpath, tv); 141 if (asroot && injail) 142 expect("priv_vfs_utimes_fowner(root, jail)", error, 0, 0); 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 } 150 151 void 152 priv_vfs_utimes_fowner_null(int asroot, int injail, struct test *test) 153 { 154 int error; 155 156 error = utimes(fpath, NULL); 157 if (asroot && injail) 158 expect("priv_vfs_utimes_fowner_null(root, jail)", error, 0, 159 0); 160 if (asroot && !injail) 161 expect("priv_vfs_utimes_fowner_null(root, !jail)", error, 0, 162 0); 163 if (!asroot && injail) 164 expect("priv_vfs_utimes_fowner_null(!root, jail)", error, 0, 165 0); 166 if (!asroot && !injail) 167 expect("priv_vfs_utimes_fowner_null(!root, !jail)", error, 0, 168 0); 169 } 170 171 void 172 priv_vfs_utimes_fother(int asroot, int injail, struct test *test) 173 { 174 struct timeval tv[2]; 175 int error; 176 177 tv[0].tv_sec = 0; 178 tv[0].tv_usec = 0; 179 tv[1].tv_sec = 0; 180 tv[1].tv_usec = 0; 181 error = utimes(fpath, tv); 182 if (asroot && injail) 183 expect("priv_vfs_utimes_fother(root, jail)", error, 0, 0); 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, -1, 188 EPERM); 189 if (!asroot && !injail) 190 expect("priv_vfs_utimes_fother(!root, !jail)", error, -1, 191 EPERM); 192 } 193 194 void 195 priv_vfs_utimes_fother_null(int asroot, int injail, struct test *test) 196 { 197 int error; 198 199 error = utimes(fpath, NULL); 200 if (asroot && injail) 201 expect("priv_vfs_utimes_fother_null(root, jail)", error, 0, 202 0); 203 if (asroot && !injail) 204 expect("priv_vfs_utimes_fother_null(root, !jail)", error, 0, 205 0); 206 if (!asroot && injail) 207 expect("priv_vfs_utimes_fother_null(!root, jail)", error, 0, 208 0); 209 if (!asroot && !injail) 210 expect("priv_vfs_utimes_fother_null(!root, !jail)", error, 0, 211 0); 212 } 213 214 void 215 priv_vfs_utimes_cleanup(int asroot, int injail, struct test *test) 216 { 217 218 if (fpath_initialized) { 219 (void)unlink(fpath); 220 fpath_initialized = 0; 221 } 222 } 223