1172106Srwatson/*- 2172106Srwatson * Copyright (c) 2006 nCircle Network Security, Inc. 3172106Srwatson * Copyright (c) 2007 Robert N. M. Watson 4172106Srwatson * All rights reserved. 5172106Srwatson * 6172106Srwatson * This software was developed by Robert N. M. Watson for the TrustedBSD 7172106Srwatson * Project under contract to nCircle Network Security, Inc. 8172106Srwatson * 9172106Srwatson * Redistribution and use in source and binary forms, with or without 10172106Srwatson * modification, are permitted provided that the following conditions 11172106Srwatson * are met: 12172106Srwatson * 1. Redistributions of source code must retain the above copyright 13172106Srwatson * notice, this list of conditions and the following disclaimer. 14172106Srwatson * 2. Redistributions in binary form must reproduce the above copyright 15172106Srwatson * notice, this list of conditions and the following disclaimer in the 16172106Srwatson * documentation and/or other materials provided with the distribution. 17172106Srwatson * 18172106Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19172106Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20172106Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21172106Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY, 22172106Srwatson * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23172106Srwatson * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 24172106Srwatson * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25172106Srwatson * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26172106Srwatson * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27172106Srwatson * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28172106Srwatson * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29172106Srwatson * 30172106Srwatson * $FreeBSD$ 31172106Srwatson */ 32172106Srwatson 33172106Srwatson/* 34172106Srwatson * Test NULL and non-NULL tv arguments to utimes() -- if NULL, then it is 35172106Srwatson * allowed without privilege if the owner or if write access is held. If 36172106Srwatson * non-NULL, privilege is required even if writable. 37172106Srwatson */ 38172106Srwatson 39172106Srwatson#include <sys/types.h> 40172106Srwatson#include <sys/stat.h> 41172106Srwatson 42172106Srwatson#include <err.h> 43172106Srwatson#include <errno.h> 44172106Srwatson#include <stdlib.h> 45172106Srwatson#include <string.h> 46172106Srwatson#include <unistd.h> 47172106Srwatson 48172106Srwatson#include "main.h" 49172106Srwatson 50172106Srwatsonstatic char fpath[1024]; 51172106Srwatsonstatic int fpath_initialized; 52172106Srwatson 53172106Srwatsonint 54172106Srwatsonpriv_vfs_utimes_froot_setup(int asroot, int injail, struct test *test) 55172106Srwatson{ 56172106Srwatson 57172106Srwatson setup_file("priv_vfs_utimes_froot_setup: fpath", fpath, 58172106Srwatson UID_ROOT, GID_WHEEL, 0600); 59172106Srwatson fpath_initialized = 1; 60172106Srwatson return (0); 61172106Srwatson} 62172106Srwatson 63172106Srwatsonint 64172106Srwatsonpriv_vfs_utimes_fowner_setup(int asroot, int injail, struct test *test) 65172106Srwatson{ 66172106Srwatson 67172106Srwatson setup_file("priv_vfs_utimes_fowner_setup: fpath", fpath, 68172106Srwatson UID_OWNER, GID_OWNER, 0600); 69172106Srwatson fpath_initialized = 1; 70172106Srwatson return (0); 71172106Srwatson} 72172106Srwatson 73172106Srwatsonint 74172106Srwatsonpriv_vfs_utimes_fother_setup(int asroot, int injail, struct test *test) 75172106Srwatson{ 76172106Srwatson 77172106Srwatson /* 78172106Srwatson * In the 'other' case, we make the file writable by the test user so 79172106Srwatson * we can evaluate the difference between setting the time to NULL, 80172106Srwatson * which is possible as a writer, and non-NULL, which requires 81172106Srwatson * ownership. 82172106Srwatson */ 83172106Srwatson setup_file("priv_vfs_utimes_fother_setup: fpath", fpath, 84172106Srwatson UID_OTHER, GID_OTHER, 0666); 85172106Srwatson fpath_initialized = 1; 86172106Srwatson return (0); 87172106Srwatson} 88172106Srwatson 89172106Srwatsonvoid 90172106Srwatsonpriv_vfs_utimes_froot(int asroot, int injail, struct test *test) 91172106Srwatson{ 92172106Srwatson struct timeval tv[2]; 93172106Srwatson int error; 94172106Srwatson 95172106Srwatson tv[0].tv_sec = 0; 96172106Srwatson tv[0].tv_usec = 0; 97172106Srwatson tv[1].tv_sec = 0; 98172106Srwatson tv[1].tv_usec = 0; 99172106Srwatson error = utimes(fpath, tv); 100172106Srwatson if (asroot && injail) 101172106Srwatson expect("priv_vfs_utimes_froot(root, jail)", error, 0, 0); 102172106Srwatson if (asroot && !injail) 103172106Srwatson expect("priv_vfs_utimes_froot(root, !jail)", error, 0, 0); 104172106Srwatson if (!asroot && injail) 105172106Srwatson expect("priv_vfs_utimes_froot(!root, jail)", error, -1, 106172106Srwatson EPERM); 107172106Srwatson if (!asroot && !injail) 108172106Srwatson expect("priv_vfs_utimes_froot(!root, !jail)", error, -1, 109172106Srwatson EPERM); 110172106Srwatson} 111172106Srwatson 112172106Srwatsonvoid 113172106Srwatsonpriv_vfs_utimes_froot_null(int asroot, int injail, struct test *test) 114172106Srwatson{ 115172106Srwatson int error; 116172106Srwatson 117172106Srwatson error = utimes(fpath, NULL); 118172106Srwatson if (asroot && injail) 119172106Srwatson expect("priv_vfs_utimes_froot_null(root, jail)", error, 0, 120172106Srwatson 0); 121172106Srwatson if (asroot && !injail) 122172106Srwatson expect("priv_vfs_utimes_froot_null(root, !jail)", error, 0, 123172106Srwatson 0); 124172106Srwatson if (!asroot && injail) 125172106Srwatson expect("priv_vfs_utimes_froot_null(!root, jail)", error, -1, 126172106Srwatson EACCES); 127172106Srwatson if (!asroot && !injail) 128172106Srwatson expect("priv_vfs_utimes_froot_null(!root, !jail)", error, -1, 129172106Srwatson EACCES); 130172106Srwatson} 131172106Srwatson 132172106Srwatsonvoid 133172106Srwatsonpriv_vfs_utimes_fowner(int asroot, int injail, struct test *test) 134172106Srwatson{ 135172106Srwatson struct timeval tv[2]; 136172106Srwatson int error; 137172106Srwatson 138172106Srwatson tv[0].tv_sec = 0; 139172106Srwatson tv[0].tv_usec = 0; 140172106Srwatson tv[1].tv_sec = 0; 141172106Srwatson tv[1].tv_usec = 0; 142172106Srwatson error = utimes(fpath, tv); 143172106Srwatson if (asroot && injail) 144172106Srwatson expect("priv_vfs_utimes_fowner(root, jail)", error, 0, 0); 145172106Srwatson if (asroot && !injail) 146172106Srwatson expect("priv_vfs_utimes_fowner(root, !jail)", error, 0, 0); 147172106Srwatson if (!asroot && injail) 148172106Srwatson expect("priv_vfs_utimes_fowner(!root, jail)", error, 0, 0); 149172106Srwatson if (!asroot && !injail) 150172106Srwatson expect("priv_vfs_utimes_fowner(!root, !jail)", error, 0, 0); 151172106Srwatson} 152172106Srwatson 153172106Srwatsonvoid 154172106Srwatsonpriv_vfs_utimes_fowner_null(int asroot, int injail, struct test *test) 155172106Srwatson{ 156172106Srwatson int error; 157172106Srwatson 158172106Srwatson error = utimes(fpath, NULL); 159172106Srwatson if (asroot && injail) 160172106Srwatson expect("priv_vfs_utimes_fowner_null(root, jail)", error, 0, 161172106Srwatson 0); 162172106Srwatson if (asroot && !injail) 163172106Srwatson expect("priv_vfs_utimes_fowner_null(root, !jail)", error, 0, 164172106Srwatson 0); 165172106Srwatson if (!asroot && injail) 166172106Srwatson expect("priv_vfs_utimes_fowner_null(!root, jail)", error, 0, 167172106Srwatson 0); 168172106Srwatson if (!asroot && !injail) 169172106Srwatson expect("priv_vfs_utimes_fowner_null(!root, !jail)", error, 0, 170172106Srwatson 0); 171172106Srwatson} 172172106Srwatson 173172106Srwatsonvoid 174172106Srwatsonpriv_vfs_utimes_fother(int asroot, int injail, struct test *test) 175172106Srwatson{ 176172106Srwatson struct timeval tv[2]; 177172106Srwatson int error; 178172106Srwatson 179172106Srwatson tv[0].tv_sec = 0; 180172106Srwatson tv[0].tv_usec = 0; 181172106Srwatson tv[1].tv_sec = 0; 182172106Srwatson tv[1].tv_usec = 0; 183172106Srwatson error = utimes(fpath, tv); 184172106Srwatson if (asroot && injail) 185172106Srwatson expect("priv_vfs_utimes_fother(root, jail)", error, 0, 0); 186172106Srwatson if (asroot && !injail) 187172106Srwatson expect("priv_vfs_utimes_fother(root, !jail)", error, 0, 0); 188172106Srwatson if (!asroot && injail) 189172106Srwatson expect("priv_vfs_utimes_fother(!root, jail)", error, -1, 190172106Srwatson EPERM); 191172106Srwatson if (!asroot && !injail) 192172106Srwatson expect("priv_vfs_utimes_fother(!root, !jail)", error, -1, 193172106Srwatson EPERM); 194172106Srwatson} 195172106Srwatson 196172106Srwatsonvoid 197172106Srwatsonpriv_vfs_utimes_fother_null(int asroot, int injail, struct test *test) 198172106Srwatson{ 199172106Srwatson int error; 200172106Srwatson 201172106Srwatson error = utimes(fpath, NULL); 202172106Srwatson if (asroot && injail) 203172106Srwatson expect("priv_vfs_utimes_fother_null(root, jail)", error, 0, 204172106Srwatson 0); 205172106Srwatson if (asroot && !injail) 206172106Srwatson expect("priv_vfs_utimes_fother_null(root, !jail)", error, 0, 207172106Srwatson 0); 208172106Srwatson if (!asroot && injail) 209172106Srwatson expect("priv_vfs_utimes_fother_null(!root, jail)", error, 0, 210172106Srwatson 0); 211172106Srwatson if (!asroot && !injail) 212172106Srwatson expect("priv_vfs_utimes_fother_null(!root, !jail)", error, 0, 213172106Srwatson 0); 214172106Srwatson} 215172106Srwatson 216172106Srwatsonvoid 217172106Srwatsonpriv_vfs_utimes_cleanup(int asroot, int injail, struct test *test) 218172106Srwatson{ 219172106Srwatson 220172106Srwatson if (fpath_initialized) { 221172106Srwatson (void)unlink(fpath); 222172106Srwatson fpath_initialized = 0; 223172106Srwatson } 224172106Srwatson} 225