1 /* 2 * Copyright (c) International Business Machines Corp., 2001 3 * 07/2001 John George 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /* 21 * Test Description: 22 * 1. Verify that the system call utime() fails to set the modification 23 * and access times of a file to the current time, under the following 24 * constraints, 25 * - The times argument is null. 26 * - The user ID of the process is not "root". 27 * 2. Verify that the system call utime() fails to set the modification 28 * and access times of a file if the specified file doesn't exist. 29 * 3. Verify that the system call utime() fails to set the modification 30 * and access times of a file to the current time, under the following 31 * constraints, 32 * - The times argument is not null. 33 * - The user ID of the process is not "root". 34 * 4. Verify that the system call utime() fails to set the modification 35 * and access times of a file that resides on a read-only file system. 36 */ 37 38 #include <errno.h> 39 #include <fcntl.h> 40 #include <pwd.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <signal.h> 44 #include <string.h> 45 #include <unistd.h> 46 #include <utime.h> 47 #include <wait.h> 48 #include <sys/stat.h> 49 #include <sys/types.h> 50 #include <sys/mount.h> 51 52 #include "test.h" 53 #include "safe_macros.h" 54 55 #define TEMP_FILE "tmp_file" 56 #define MNT_POINT "mntpoint" 57 58 char *TCID = "utime06"; 59 static struct passwd *ltpuser; 60 static const struct utimbuf times; 61 static const char *dev; 62 static int mount_flag; 63 static void setup_nobody(void); 64 static void cleanup_nobody(void); 65 66 struct test_case_t { 67 char *pathname; 68 int exp_errno; 69 const struct utimbuf *times; 70 void (*setup_func)(void); 71 void (*cleanup_func)(void); 72 } Test_cases[] = { 73 {TEMP_FILE, EACCES, NULL, setup_nobody, cleanup_nobody}, 74 {"", ENOENT, NULL, NULL, NULL}, 75 {TEMP_FILE, EPERM, ×, setup_nobody, cleanup_nobody}, 76 {MNT_POINT, EROFS, NULL, NULL, NULL}, 77 }; 78 79 int TST_TOTAL = ARRAY_SIZE(Test_cases); 80 static void setup(void); 81 static void utime_verify(const struct test_case_t *); 82 static void cleanup(void); 83 84 int main(int ac, char **av) 85 { 86 int lc; 87 int i; 88 89 tst_parse_opts(ac, av, NULL, NULL); 90 91 setup(); 92 93 for (lc = 0; TEST_LOOPING(lc); lc++) { 94 tst_count = 0; 95 for (i = 0; i < TST_TOTAL; i++) 96 utime_verify(&Test_cases[i]); 97 } 98 99 cleanup(); 100 tst_exit(); 101 } 102 103 static void setup(void) 104 { 105 const char *fs_type; 106 107 tst_sig(NOFORK, DEF_HANDLER, cleanup); 108 109 tst_require_root(); 110 111 TEST_PAUSE; 112 113 tst_tmpdir(); 114 115 SAFE_TOUCH(cleanup, TEMP_FILE, 0644, NULL); 116 117 fs_type = tst_dev_fs_type(); 118 dev = tst_acquire_device(cleanup); 119 if (!dev) 120 tst_brkm(TCONF, cleanup, "Failed to acquire test device"); 121 122 tst_mkfs(cleanup, dev, fs_type, NULL, NULL); 123 124 SAFE_MKDIR(cleanup, MNT_POINT, 0644); 125 if (mount(dev, MNT_POINT, fs_type, MS_RDONLY, NULL) < 0) { 126 tst_brkm(TBROK | TERRNO, cleanup, 127 "mount device:%s failed", dev); 128 } 129 mount_flag = 1; 130 131 ltpuser = SAFE_GETPWNAM(cleanup, "nobody"); 132 } 133 134 static void utime_verify(const struct test_case_t *test) 135 { 136 if (test->setup_func != NULL) 137 test->setup_func(); 138 139 TEST(utime(test->pathname, test->times)); 140 141 if (test->cleanup_func != NULL) 142 test->cleanup_func(); 143 144 if (TEST_RETURN != -1) { 145 tst_resm(TFAIL, "utime succeeded unexpectedly"); 146 return; 147 } 148 149 if (TEST_ERRNO == test->exp_errno) { 150 tst_resm(TPASS | TTERRNO, "utime failed as expected"); 151 } else { 152 tst_resm(TFAIL | TTERRNO, 153 "utime failed unexpectedly; expected: %d - %s", 154 test->exp_errno, strerror(test->exp_errno)); 155 } 156 } 157 158 static void setup_nobody(void) 159 { 160 SAFE_SETEUID(cleanup, ltpuser->pw_uid); 161 } 162 163 static void cleanup_nobody(void) 164 { 165 SAFE_SETEUID(cleanup, 0); 166 } 167 168 static void cleanup(void) 169 { 170 if (mount_flag && tst_umount(MNT_POINT) < 0) 171 tst_resm(TWARN | TERRNO, "umount device:%s failed", dev); 172 173 if (dev) 174 tst_release_device(dev); 175 176 tst_rmdir(); 177 } 178