blob: ddf9aff007cd0bb2bb6852f0d3e6a1891514ad2e [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
21 * NAME
22 * mkdir02
23 *
24 * DESCRIPTION
25 * This test will verify that new directory created
26 * by mkdir(2) inherites the group ID from the parent
27 * directory and S_ISGID bit, if the S_ISGID bit is set
28 * in the parent directory.
subrata_modakbdbaec52009-02-26 12:14:51 +000029 *
plars865695b2001-08-27 22:15:12 +000030 * ALGORITHM
31 * Setup:
32 * Setup signal handling.
33 * Pause for SIGUSR1 if option specified.
34 * Create temporary directory.
35 * Give write permission on temporary directory for all users.
36 * set up umask
37 *
38 * Test:
39 * Loop if the proper options are given.
40 * fork the first child as ltpuser1
41 * create a directory tstdir1 with S_ISGID set
42 * fork the second child as ltpuser2
43 * create a directtory tstdir2 user tstdir1
44 * check tstdir2's group ID and the S_ISGID bit
45 * if they are the same as tstdir1's
46 * PASS
47 * else FAIL
48 * Cleanup:
49 * Print errno log and/or timing stats if options given
50 * Delete the temporary directory created.*
51 * USAGE
52 * mkdir02 [-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#include <errno.h>
69#include <string.h>
70#include <signal.h>
71#include <sys/stat.h>
72#include <sys/types.h>
73#include <fcntl.h>
74#include <pwd.h>
75#include <sys/wait.h>
76#include <unistd.h>
subrata_modak4bb656a2009-02-26 12:02:09 +000077#include "test.h"
plars865695b2001-08-27 22:15:12 +000078
79void setup();
80void cleanup();
subrata_modak56207ce2009-03-23 13:35:39 +000081extern struct passwd *my_getpwnam(char *);
plars865695b2001-08-27 22:15:12 +000082
83#define PERMS 0777
84
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020085char *TCID = "mkdir02";
86int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000087
subrata_modak56207ce2009-03-23 13:35:39 +000088char tstdir1[100];
89char tstdir2[100];
plars865695b2001-08-27 22:15:12 +000090
plars513a4a22001-09-07 17:30:55 +000091char user1name[] = "nobody";
92char user2name[] = "bin";
plars865695b2001-08-27 22:15:12 +000093
subrata_modak56207ce2009-03-23 13:35:39 +000094int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +000095{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020096 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020097 const char *msg;
subrata_modak56207ce2009-03-23 13:35:39 +000098 struct stat buf, buf1;
plars865695b2001-08-27 22:15:12 +000099 pid_t pid, pid1;
100 struct passwd *ltpuser1;
101 struct passwd *ltpuser2;
102 int rval, status;
103
104 /*
105 * parse standard options
106 */
Garrett Cooper45e285d2010-11-22 12:19:25 -0800107 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -0800108 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
plars865695b2001-08-27 22:15:12 +0000109 }
110
111 /*
112 * perform global setup for test
113 */
114 setup();
subrata_modakbdbaec52009-02-26 12:14:51 +0000115
plars865695b2001-08-27 22:15:12 +0000116 /*
117 * check looping state if -i option given
118 */
subrata_modak56207ce2009-03-23 13:35:39 +0000119 for (lc = 0; TEST_LOOPING(lc); lc++) {
120
Caspar Zhangd59a6592013-03-07 14:59:12 +0800121 tst_count = 0;
subrata_modak56207ce2009-03-23 13:35:39 +0000122
plars865695b2001-08-27 22:15:12 +0000123 /* check the inherited group ID */
124
subrata_modak4bb656a2009-02-26 12:02:09 +0000125 /*
plars865695b2001-08-27 22:15:12 +0000126 * first, fork the first child, set to ltpuser1's uid and gid,
127 * create a directory, with S_ISGID bit set
128 */
129
130 ltpuser1 = my_getpwnam(user1name);
subrata_modakbdbaec52009-02-26 12:14:51 +0000131 sprintf(tstdir1, "tstdir1.%d", getpid());
plars865695b2001-08-27 22:15:12 +0000132
robbiewd34d5812005-07-11 22:28:09 +0000133 if ((pid = FORK_OR_VFORK()) < 0) {
plars865695b2001-08-27 22:15:12 +0000134 tst_brkm(TFAIL, cleanup, "fork() failed");
Garrett Cooper2c282152010-12-16 00:55:50 -0800135
plars865695b2001-08-27 22:15:12 +0000136 }
137
subrata_modak56207ce2009-03-23 13:35:39 +0000138 if (pid == 0) { /* first child */
plars865695b2001-08-27 22:15:12 +0000139 rval = setregid(ltpuser1->pw_gid, ltpuser1->pw_gid);
140 if (rval < 0) {
141 perror("setregid");
142 tst_resm(TFAIL, "setregid failed to "
143 "to set the real gid to %d and "
144 "effective gid to %d",
145 ltpuser1->pw_gid, ltpuser1->pw_gid);
146 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800147
plars865695b2001-08-27 22:15:12 +0000148 }
subrata_modak4bb656a2009-02-26 12:02:09 +0000149 /* being ltupuser1 */
plars865695b2001-08-27 22:15:12 +0000150 rval = setreuid(ltpuser1->pw_uid, ltpuser1->pw_uid);
151 if (rval < 0) {
152 perror("setreuid");
153 tst_resm(TFAIL, "setreuid failed to "
154 "to set the real uid to %d and "
155 "effective uid to %d",
156 ltpuser1->pw_uid, ltpuser1->pw_uid);
157 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800158
plars865695b2001-08-27 22:15:12 +0000159 }
subrata_modak56207ce2009-03-23 13:35:39 +0000160
subrata_modak4bb656a2009-02-26 12:02:09 +0000161 /*
plars865695b2001-08-27 22:15:12 +0000162 * create a direcoty with S_ISGID bit set
163 * and the group ID is ltpuser1
164 */
165 if (mkdir(tstdir1, PERMS) != 0) {
166 perror("mkdir");
167 tst_resm(TFAIL, "mkdir() failed to create"
subrata_modak56207ce2009-03-23 13:35:39 +0000168 " a directory with Set "
169 " group ID turn on ");
plars865695b2001-08-27 22:15:12 +0000170 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800171
plars865695b2001-08-27 22:15:12 +0000172 }
173 if (stat(tstdir1, &buf1) == -1) {
174 perror("stat");
subrata_modak4bb656a2009-02-26 12:02:09 +0000175 tst_resm(TFAIL,
subrata_modak56207ce2009-03-23 13:35:39 +0000176 "failed to stat the new directory"
177 "in mkdir()");
plars865695b2001-08-27 22:15:12 +0000178 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800179
plars865695b2001-08-27 22:15:12 +0000180 }
subrata_modak56207ce2009-03-23 13:35:39 +0000181 if (chmod(tstdir1, buf1.st_mode | S_ISGID) != 0) {
plars865695b2001-08-27 22:15:12 +0000182 perror("chmod");
183 tst_resm(TFAIL, "failed to set S_ISGID bit");
184 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800185
plars865695b2001-08-27 22:15:12 +0000186 }
subrata_modak56207ce2009-03-23 13:35:39 +0000187
plars865695b2001-08-27 22:15:12 +0000188 /* Successfully create the parent directory */
189 exit(0);
Garrett Cooper2c282152010-12-16 00:55:50 -0800190
plars865695b2001-08-27 22:15:12 +0000191 }
192 wait(&status);
193 if (WEXITSTATUS(status) != 0) {
194 tst_brkm(TFAIL, cleanup,
195 "Test to attempt to make a directory"
196 " inherits group ID FAILED ");
197 }
198 /*
199 * fork the second child process, set to ltpuser2's uid and gid
200 * create a sub directory under the directory
201 * just created by child process 1
202 * check the group ID of the sub directory
203 * should inherit from parent directory
204 */
205
206 ltpuser2 = my_getpwnam(user2name);
207 sprintf(tstdir2, "%s/tstdir2.%d", tstdir1, getpid());
robbiewd34d5812005-07-11 22:28:09 +0000208 if ((pid1 = FORK_OR_VFORK()) < 0) {
plars865695b2001-08-27 22:15:12 +0000209 perror("fork failed");
210 tst_brkm(TFAIL, cleanup, "fork() failed");
Garrett Cooper2c282152010-12-16 00:55:50 -0800211
subrata_modak56207ce2009-03-23 13:35:39 +0000212 } else if (pid1 == 0) { /* second child */
plars865695b2001-08-27 22:15:12 +0000213
214 /* being user ltpuser2 */
215 rval = setregid(ltpuser2->pw_gid, ltpuser2->pw_gid);
216 if (rval < 0) {
217 tst_resm(TFAIL, "setregid failed to "
218 "to set the real gid to %d and "
219 "effective gid to %d",
220 ltpuser2->pw_gid, ltpuser2->pw_gid);
221 perror("setregid");
222 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800223
plars865695b2001-08-27 22:15:12 +0000224 }
225 rval = setreuid(ltpuser2->pw_uid, ltpuser2->pw_uid);
226 if (rval < 0) {
227 tst_resm(TFAIL, "setreuid failed to "
228 "to set the real uid to %d and "
229 "effective uid to %d",
230 ltpuser2->pw_uid, ltpuser2->pw_uid);
231 perror("setreuid");
232 exit(1);
subrata_modak56207ce2009-03-23 13:35:39 +0000233
plars865695b2001-08-27 22:15:12 +0000234 }
subrata_modak56207ce2009-03-23 13:35:39 +0000235
subrata_modak4bb656a2009-02-26 12:02:09 +0000236 /*
237 * create a sub direcoty
plars865695b2001-08-27 22:15:12 +0000238 * under the directory just created
239 * by ltpuser1
240 */
241 if (mkdir(tstdir2, PERMS) != 0) {
242 tst_resm(TFAIL, "mkdir() failed to create"
subrata_modak56207ce2009-03-23 13:35:39 +0000243 " a directory %s under %s ", tstdir2,
244 tstdir1);
plars865695b2001-08-27 22:15:12 +0000245 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800246
plars865695b2001-08-27 22:15:12 +0000247 }
subrata_modak4bb656a2009-02-26 12:02:09 +0000248 /*
249 * check the group ID
plars865695b2001-08-27 22:15:12 +0000250 * should not be the same as the current processs's
251 * since parent directory is set with S_ISGID bit
252 */
253 if (stat(tstdir2, &buf) == -1) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000254 tst_resm(TFAIL,
subrata_modak56207ce2009-03-23 13:35:39 +0000255 "failed to stat the new directory"
256 "in mkdir()");
plars865695b2001-08-27 22:15:12 +0000257 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800258
plars865695b2001-08-27 22:15:12 +0000259 }
260 if (stat(tstdir1, &buf1) == -1) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000261 tst_resm(TFAIL,
subrata_modak56207ce2009-03-23 13:35:39 +0000262 "failed to stat the new directory"
263 "in mkdir()");
plars865695b2001-08-27 22:15:12 +0000264 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800265
plars865695b2001-08-27 22:15:12 +0000266 }
subrata_modak56207ce2009-03-23 13:35:39 +0000267 if (buf.st_gid != buf1.st_gid) {
plars865695b2001-08-27 22:15:12 +0000268 tst_resm(TFAIL, "mkdir() FAILED to inherit "
subrata_modak56207ce2009-03-23 13:35:39 +0000269 " the group ID %d from parent "
270 " directory %d",
271 buf.st_gid, buf1.st_gid);
plars865695b2001-08-27 22:15:12 +0000272 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800273
plars865695b2001-08-27 22:15:12 +0000274 }
subrata_modak56207ce2009-03-23 13:35:39 +0000275
plars865695b2001-08-27 22:15:12 +0000276 /* check the S_ISGID bit */
subrata_modak56207ce2009-03-23 13:35:39 +0000277 if (!(buf.st_mode & S_ISGID)) {
plars865695b2001-08-27 22:15:12 +0000278 tst_resm(TFAIL, "mkdir() FAILED to inherit "
subrata_modak56207ce2009-03-23 13:35:39 +0000279 " the S_ISGID bit from parent "
280 " directory");
plars865695b2001-08-27 22:15:12 +0000281 exit(1);
Garrett Cooper2c282152010-12-16 00:55:50 -0800282
plars865695b2001-08-27 22:15:12 +0000283 }
284 /* PASS */
285 exit(0);
Garrett Cooper2c282152010-12-16 00:55:50 -0800286
plars865695b2001-08-27 22:15:12 +0000287 }
subrata_modak56207ce2009-03-23 13:35:39 +0000288
plars865695b2001-08-27 22:15:12 +0000289 waitpid(pid1, &status, 0);
290 if (WEXITSTATUS(status) == 0) {
291 tst_resm(TPASS, "Test to attempt to make a directory"
292 " inherits group ID SUCCEEDED ");
293 } else {
294 tst_resm(TFAIL, "Test to attempt to make a directory"
295 " inherits group ID FAILED");
296 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800297 }
subrata_modak56207ce2009-03-23 13:35:39 +0000298
Garrett Cooper2c282152010-12-16 00:55:50 -0800299 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000300
plars865695b2001-08-27 22:15:12 +0000301 /*
302 * cleanup and exit
303 */
304 cleanup();
subrata_modakbdbaec52009-02-26 12:14:51 +0000305
Garrett Cooper7d0a4a52010-12-16 10:05:08 -0800306 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800307}
plars865695b2001-08-27 22:15:12 +0000308
309/*
310 * setup() - performs all ONE TIME setup for this test.
311 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400312void setup(void)
plars865695b2001-08-27 22:15:12 +0000313{
Nicolas Jolyd4ceb372014-06-22 17:03:57 +0200314 tst_require_root(NULL);
subrata_modakbdbaec52009-02-26 12:14:51 +0000315
plars865695b2001-08-27 22:15:12 +0000316 tst_sig(FORK, DEF_HANDLER, cleanup);
317
plars865695b2001-08-27 22:15:12 +0000318 TEST_PAUSE;
subrata_modakbdbaec52009-02-26 12:14:51 +0000319
plars865695b2001-08-27 22:15:12 +0000320 /* Create a temporary directory and make it current. */
321 tst_tmpdir();
subrata_modakbdbaec52009-02-26 12:14:51 +0000322
plars865695b2001-08-27 22:15:12 +0000323 umask(0);
324}
325
plars865695b2001-08-27 22:15:12 +0000326/*
327 * cleanup() - performs all ONE TIME cleanup for this test at
328 * completion or premature exit.
329 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400330void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000331{
plars865695b2001-08-27 22:15:12 +0000332
333 /*
334 * Remove the temporary directory.
335 */
336 tst_rmdir();
subrata_modakbdbaec52009-02-26 12:14:51 +0000337
plars865695b2001-08-27 22:15:12 +0000338 /*
339 * Exit with return code appropriate for results.
340 */
Garrett Cooper2c282152010-12-16 00:55:50 -0800341
Chris Dearmanec6edca2012-10-17 19:54:01 -0700342}