1 /*
2  * Copyright (c) International Business Machines  Corp., 2001
3  *  07/2001 Ported by Wayne Boyer
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 Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /*
21  * DESCRIPTION
22  *	This test will verify the mkdir(2) syscall basic functionality
23  */
24 
25 #include <errno.h>
26 #include <string.h>
27 #include <signal.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <pwd.h>
33 #include "test.h"
34 #include "safe_macros.h"
35 
36 void setup();
37 void cleanup();
38 
39 #define PERMS		0777
40 
41 char *TCID = "mkdir05";
42 int TST_TOTAL = 1;
43 
44 char nobody_uid[] = "nobody";
45 struct passwd *ltpuser;
46 
47 char tstdir1[100];
48 
main(int ac,char ** av)49 int main(int ac, char **av)
50 {
51 	int lc;
52 	struct stat buf;
53 
54 	/*
55 	 * parse standard options
56 	 */
57 	tst_parse_opts(ac, av, NULL, NULL);
58 
59 	/*
60 	 * perform global setup for test
61 	 */
62 	setup();
63 
64 	/*
65 	 * check looping state if -i option given
66 	 */
67 	for (lc = 0; TEST_LOOPING(lc); lc++) {
68 
69 		tst_count = 0;
70 
71 		/*
72 		 * TEST mkdir() base functionality
73 		 */
74 
75 		/* Initialize the test directory name */
76 		sprintf(tstdir1, "tstdir1.%d", getpid());
77 
78 		/* Call mkdir(2) using the TEST macro */
79 		TEST(mkdir(tstdir1, PERMS));
80 
81 		if (TEST_RETURN == -1) {
82 			tst_resm(TFAIL, "mkdir(%s, %#o) Failed",
83 				 tstdir1, PERMS);
84 			continue;
85 		}
86 
87 		SAFE_STAT(cleanup, tstdir1, &buf);
88 		/* check the owner */
89 		if (buf.st_uid != geteuid()) {
90 			tst_resm(TFAIL, "mkdir() FAILED to set owner ID"
91 				 " as process's effective ID");
92 			continue;
93 		}
94 		/* check the group ID */
95 		if (buf.st_gid != getegid()) {
96 			tst_resm(TFAIL, "mkdir() failed to set group ID"
97 				 " as the process's group ID");
98 			continue;
99 		}
100 		tst_resm(TPASS, "mkdir() functionality is correct");
101 
102 		/* clean up things in case we are looping */
103 		SAFE_RMDIR(cleanup, tstdir1);
104 
105 	}
106 
107 	cleanup();
108 	tst_exit();
109 }
110 
111 /*
112  * setup() - performs all ONE TIME setup for this test.
113  */
setup(void)114 void setup(void)
115 {
116 	tst_require_root();
117 
118 	ltpuser = getpwnam(nobody_uid);
119 	if (setuid(ltpuser->pw_uid) == -1) {
120 		tst_resm(TINFO, "setuid failed to "
121 			 "to set the effective uid to %d", ltpuser->pw_uid);
122 		perror("setuid");
123 	}
124 
125 	tst_sig(FORK, DEF_HANDLER, cleanup);
126 
127 	TEST_PAUSE;
128 
129 	/* Create a temporary directory and make it current. */
130 	tst_tmpdir();
131 }
132 
133 /*
134  * cleanup() - performs all ONE TIME cleanup for this test at
135  *             completion or premature exit.
136  */
cleanup(void)137 void cleanup(void)
138 {
139 
140 	/*
141 	 * Remove the temporary directory.
142 	 */
143 	tst_rmdir();
144 
145 	/*
146 	 * Exit with return code appropriate for results.
147 	 */
148 
149 }
150