1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 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 * NAME 22 * mkdir04 23 * 24 * DESCRIPTION 25 * 26 * ALGORITHM 27 * Setup: 28 * Setup signal handling. 29 * Pause for SIGUSR1 if option specified. 30 * Create temporary directory. 31 * 32 * Test: 33 * Loop if the proper options are given. 34 * fork the first child 35 * set to be ltpuser1 36 * create a dirctory tstdir1 with 0700 permission 37 * fork the second child 38 * set to ltpuser2 39 * try to create a subdirectory tstdir2 under tstdir1 40 * check the returnvalue, if succeeded (return=0) 41 * Log the errno and Issue a FAIL message. 42 * Otherwise, 43 * Verify the errno 44 * if equals to EACCES, 45 * Issue Pass message. 46 * Otherwise, 47 * Issue Fail message. 48 * Cleanup: 49 * Print errno log and/or timing stats if options given 50 * Delete the temporary directory created. 51 * USAGE 52 * mkdir04 [-c n] [-e] [-f] [-i n] [-I x] [-P x] [-t] 53 * where, -c n : Run n copies concurrently. 54 * -e : Turn on errno logging. 55 * -f : Turn off functionality Testing. 56 * -i n : Execute test n times. 57 * -I x : Execute test for x seconds. 58 * -P x : Pause for x seconds between iterations. 59 * -t : Turn on syscall timing. 60 * 61 * HISTORY 62 * 07/2001 Ported by Wayne Boyer 63 * 64 * RESTRICTIONS 65 * None. 66 * 67 */ 68 69 #include <errno.h> 70 #include <string.h> 71 #include <signal.h> 72 #include <sys/stat.h> 73 #include <sys/types.h> 74 #include <fcntl.h> 75 #include <pwd.h> 76 #include <sys/wait.h> 77 #include <unistd.h> 78 79 #include "test.h" 80 #include "safe_macros.h" 81 82 void setup(); 83 void cleanup(); 84 int fail; 85 86 #define PERMS 0700 87 88 static uid_t nobody_uid, bin_uid; 89 90 char *TCID = "mkdir04"; 91 int TST_TOTAL = 1; 92 int fail; 93 94 char tstdir1[100]; 95 char tstdir2[100]; 96 97 int main(int ac, char **av) 98 { 99 int lc; 100 int rval; 101 pid_t pid, pid1; 102 int status; 103 104 /* 105 * parse standard options 106 */ 107 tst_parse_opts(ac, av, NULL, NULL); 108 109 /* 110 * perform global setup for test 111 */ 112 setup(); 113 114 /* 115 * check looping state if -i option given 116 */ 117 for (lc = 0; TEST_LOOPING(lc); lc++) { 118 119 tst_count = 0; 120 121 /* Initialize the test directories name */ 122 sprintf(tstdir1, "tstdir1.%d", getpid()); 123 if ((pid = FORK_OR_VFORK()) < 0) { 124 tst_brkm(TBROK, cleanup, "fork #1 failed"); 125 } 126 127 if (pid == 0) { /* first child */ 128 rval = setreuid(nobody_uid, nobody_uid); 129 if (rval < 0) { 130 tst_resm(TFAIL | TERRNO, "setreuid failed to " 131 "to set the real uid to %d and " 132 "effective uid to %d", 133 nobody_uid, nobody_uid); 134 exit(1); 135 } 136 /* create the parent directory with 0700 permits */ 137 if (mkdir(tstdir1, PERMS) == -1) { 138 tst_resm(TFAIL | TERRNO, 139 "mkdir(%s, %#o) Failed", 140 tstdir1, PERMS); 141 exit(1); 142 } 143 /* create tstdir1 succeeded */ 144 exit(0); 145 } 146 wait(&status); 147 if (WEXITSTATUS(status) != 0) { 148 tst_brkm(TFAIL, cleanup, 149 "Test to check mkdir EACCES failed" 150 "in create parent directory"); 151 } 152 153 sprintf(tstdir2, "%s/tst", tstdir1); 154 155 if ((pid1 = FORK_OR_VFORK()) < 0) { 156 tst_brkm(TBROK, cleanup, "fork #2 failed"); 157 } 158 159 if (pid1 == 0) { /* second child */ 160 rval = setreuid(bin_uid, bin_uid); 161 if (rval < 0) { 162 tst_resm(TFAIL | TERRNO, "setreuid failed to " 163 "to set the real uid to %d and " 164 "effective uid to %d", 165 bin_uid, bin_uid); 166 exit(1); 167 } 168 if (mkdir(tstdir2, PERMS) != -1) { 169 tst_resm(TFAIL, "mkdir(%s, %#o) unexpected " 170 "succeeded", tstdir2, PERMS); 171 exit(1); 172 } 173 if (errno != EACCES) { 174 tst_resm(TFAIL, "Expected EACCES got %d", 175 errno); 176 exit(1); 177 } 178 /* PASS */ 179 exit(0); 180 } 181 waitpid(pid1, &status, 0); 182 if (WEXITSTATUS(status) == 0) { 183 tst_resm(TPASS, "Test to attempt to creat a directory " 184 "in a directory having no permissions " 185 "SUCCEEDED in setting errno to EACCES"); 186 } else { 187 tst_resm(TFAIL, "Test to attempt to creat a directory " 188 "in a directory having no permissions FAILED"); 189 cleanup(); 190 } 191 } 192 193 /* 194 * cleanup and exit 195 */ 196 cleanup(); 197 tst_exit(); 198 199 } 200 201 /* 202 * setup() - performs all ONE TIME setup for this test. 203 */ 204 void setup(void) 205 { 206 struct passwd *pw; 207 208 tst_require_root(); 209 210 pw = SAFE_GETPWNAM(NULL, "nobody"); 211 nobody_uid = pw->pw_uid; 212 #ifndef ANDROID 213 pw = SAFE_GETPWNAM(NULL, "bin"); 214 #else 215 // user "bin" does not exist in Android kernel 216 pw = SAFE_GETPWNAM(NULL, "everybody"); 217 #endif 218 bin_uid = pw->pw_uid; 219 220 tst_sig(FORK, DEF_HANDLER, cleanup); 221 222 TEST_PAUSE; 223 224 /* Create a temporary directory and make it current. */ 225 tst_tmpdir(); 226 227 umask(0); 228 } 229 230 /* 231 * cleanup() - performs all ONE TIME cleanup for this test at 232 * completion or premature exit. 233 */ 234 void cleanup(void) 235 { 236 237 /* 238 * Remove the temporary directory. 239 */ 240 tst_rmdir(); 241 242 /* 243 * Exit with return code appropriate for results. 244 */ 245 246 } 247