mkdir04.c revision 4548c6cf9bcdd96d8303caa4130ab638b61f8a30
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#include "test.h" 79#include "usctest.h" 80 81void setup(); 82void cleanup(); 83extern struct passwd *my_getpwnam(char *); 84int fail; 85 86#define PERMS 0700 87 88char user1name[] = "nobody"; 89char user2name[] = "bin"; 90 91char *TCID = "mkdir04"; /* Test program identifier. */ 92int TST_TOTAL = 1; /* Total number of test cases. */ 93int fail; 94 95char tstdir1[100]; 96char tstdir2[100]; 97 98int exp_enos[] = { EACCES, 0 }; /* List must end with 0 */ 99 100int main(int ac, char **av) 101{ 102 int lc; /* loop counter */ 103 char *msg; /* message returned from parse_opts */ 104 int rval; 105 pid_t pid, pid1; 106 int status; 107 struct passwd *ltpuser1, *ltpuser2; 108 109 /* 110 * parse standard options 111 */ 112 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { 113 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); 114 } 115 116 /* 117 * perform global setup for test 118 */ 119 setup(); 120 121 /* set the expected errnos... */ 122 TEST_EXP_ENOS(exp_enos); 123 124 /* 125 * check looping state if -i option given 126 */ 127 for (lc = 0; TEST_LOOPING(lc); lc++) { 128 129 Tst_count = 0; 130 131 /* Initialize the test directories name */ 132 sprintf(tstdir1, "tstdir1.%d", getpid()); 133 ltpuser1 = my_getpwnam(user1name); 134 135 if ((pid = FORK_OR_VFORK()) < 0) { 136 tst_brkm(TBROK, cleanup, "fork #1 failed"); 137 } 138 139 if (pid == 0) { /* first child */ 140 /* set to ltpuser1 */ 141 rval = setreuid(ltpuser1->pw_uid, ltpuser1->pw_uid); 142 if (rval < 0) { 143 tst_resm(TFAIL, "setreuid failed to " 144 "to set the real uid to %d and " 145 "effective uid to %d", 146 ltpuser1->pw_uid, ltpuser1->pw_uid); 147 perror("setreuid"); 148 exit(1); 149 } 150 /* create the parent directory with 0700 permits */ 151 if (mkdir(tstdir1, PERMS) == -1) { 152 tst_resm(TFAIL, "mkdir(%s, %#o) Failed", 153 tstdir1, PERMS); 154 exit(1); 155 } 156 /* create tstdir1 succeeded */ 157 exit(0); 158 } 159 wait(&status); 160 if (WEXITSTATUS(status) != 0) { 161 tst_brkm(TFAIL, cleanup, 162 "Test to check mkdir EACCES failed" 163 "in create parent directory"); 164 } 165 166 sprintf(tstdir2, "%s/tst", tstdir1); 167 ltpuser2 = my_getpwnam(user2name); 168 169 if ((pid1 = FORK_OR_VFORK()) < 0) { 170 tst_brkm(TBROK, cleanup, "fork #2 failed"); 171 } 172 173 if (pid1 == 0) { /* second child */ 174 /* set to ltpuser2 */ 175 rval = setreuid(ltpuser2->pw_uid, ltpuser2->pw_uid); 176 if (rval < 0) { 177 tst_resm(TFAIL, "setreuid failed to " 178 "to set the real uid to %d and " 179 "effective uid to %d", 180 ltpuser2->pw_uid, ltpuser2->pw_uid); 181 perror("setreuid"); 182 exit(1); 183 } 184 if (mkdir(tstdir2, PERMS) != -1) { 185 tst_resm(TFAIL, "mkdir(%s, %#o) unexpected " 186 "succeeded", tstdir2, PERMS); 187 exit(1); 188 } 189 if (errno != EACCES) { 190 tst_resm(TFAIL, "Expected EACCES got %d", 191 errno); 192 exit(1); 193 } 194 /* PASS */ 195 exit(0); 196 } 197 waitpid(pid1, &status, 0); 198 if (WEXITSTATUS(status) == 0) { 199 tst_resm(TPASS, "Test to attempt to creat a directory " 200 "in a directory having no permissions " 201 "SUCCEEDED in setting errno to EACCES"); 202 } else { 203 tst_resm(TFAIL, "Test to attempt to creat a directory " 204 "in a directory having no permissions FAILED"); 205 cleanup(); 206 } 207 } 208 209 /* 210 * cleanup and exit 211 */ 212 cleanup(); 213 tst_exit(); 214 215} 216 217/* 218 * setup() - performs all ONE TIME setup for this test. 219 */ 220void setup() 221{ 222 /* must run as root */ 223 if (geteuid() != 0) { 224 tst_brkm(TBROK, NULL, "Must run this as root"); 225 } 226 227 tst_sig(FORK, DEF_HANDLER, cleanup); 228 229 TEST_PAUSE; 230 231 /* Create a temporary directory and make it current. */ 232 tst_tmpdir(); 233 234 umask(0); 235} 236 237/* 238 * cleanup() - performs all ONE TIME cleanup for this test at 239 * completion or premature exit. 240 */ 241void cleanup() 242{ 243 /* 244 * print timing stats if that option was specified. 245 * print errno log if that option was specified. 246 */ 247 TEST_CLEANUP; 248 249 /* 250 * Remove the temporary directory. 251 */ 252 tst_rmdir(); 253 254 /* 255 * Exit with return code appropriate for results. 256 */ 257 258} 259