blob: eca73db9a5a6dc2629bc5702e076354467cf44b4 [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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
vapier37cf54a2007-04-13 20:58:17 +000020/*
nstrazfa31d552002-05-14 16:50:06 +000021 * Test Name: fchown05
plars865695b2001-08-27 22:15:12 +000022 *
23 * Test Description:
24 * Verify that, fchown(2) succeeds to change the owner and group of a file
vapier37cf54a2007-04-13 20:58:17 +000025 * specified by file descriptor to any numeric owner(uid)/group(gid) values
plars865695b2001-08-27 22:15:12 +000026 * when invoked by super-user.
27 *
28 * Expected Result:
vapier37cf54a2007-04-13 20:58:17 +000029 * fchown(2) should return 0 and the ownership set on the file should match
plars865695b2001-08-27 22:15:12 +000030 * the numeric values contained in owner and group respectively.
vapier37cf54a2007-04-13 20:58:17 +000031 *
plars865695b2001-08-27 22:15:12 +000032 * Algorithm:
33 * Setup:
34 * Setup signal handling.
35 * Create temporary directory.
36 * Pause for SIGUSR1 if option specified.
37 *
38 * Test:
39 * Loop if the proper options are given.
40 * Execute system call
41 * Check return code, if system call failed (return=-1)
42 * Log the errno and Issue a FAIL message.
43 * Otherwise,
vapier37cf54a2007-04-13 20:58:17 +000044 * Verify the Functionality of system call
plars865695b2001-08-27 22:15:12 +000045 * if successful,
46 * Issue Functionality-Pass message.
47 * Otherwise,
48 * Issue Functionality-Fail message.
49 * Cleanup:
50 * Print errno log and/or timing stats if options given
51 * Delete the temporary directory created.
52 *
53 * Usage: <for command-line>
nstrazfa31d552002-05-14 16:50:06 +000054 * fchown05 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
plars865695b2001-08-27 22:15:12 +000055 * where, -c n : Run n copies concurrently.
56 * -f : Turn off functionality Testing.
57 * -i n : Execute test n times.
58 * -I x : Execute test for x seconds.
59 * -P x : Pause for x seconds between iterations.
60 * -t : Turn on syscall timing.
61 *
62 * HISTORY
63 * 07/2001 Ported by Wayne Boyer
64 *
65 * RESTRICTIONS:
66 * This test should be run by 'super-user' (root) only.
67 *
68 */
69
70#include <stdio.h>
71#include <sys/types.h>
72#include <sys/stat.h>
73#include <sys/fcntl.h>
74#include <errno.h>
75#include <string.h>
76#include <signal.h>
77
78#include "test.h"
79#include "usctest.h"
80
81#define FILE_MODE S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
82#define TESTFILE "testfile"
83
84int fildes; /* File descriptor for the test file */
vapier37cf54a2007-04-13 20:58:17 +000085char *TCID = "fchown05"; /* Test program identifier. */
86int TST_TOTAL = 5; /* Total number of test conditions */
plars865695b2001-08-27 22:15:12 +000087extern int Tst_count; /* Test Case counter for tst_* routines */
88
89struct test_case_t { /* Struct. for for test case looping */
90 char *desc;
91 uid_t user_id;
92 gid_t group_id;
93} Test_cases[] = {
vapier37cf54a2007-04-13 20:58:17 +000094 {
95 "Change Owner/Group ids", 700, 701}, {
96 "Change Owner id only", 702, -1}, {
97 "Change Owner id only", 703, 701}, {
98 "Change Group id only", -1, 704}, {
99 "Change Group id only", 703, 705}, {
100 NULL, 0, 0}
plars865695b2001-08-27 22:15:12 +0000101};
102
103void setup(); /* setup function for the test */
104void cleanup(); /* cleanup function for the test */
105
vapier37cf54a2007-04-13 20:58:17 +0000106int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000107{
108 struct stat stat_buf; /* stat(2) struct contents */
109 int lc; /* loop counter */
110 char *msg; /* message returned from parse_opts */
111 int ind; /* counter variable for chmod(2) tests */
112 uid_t User_id; /* user id of the user set for testfile */
113 gid_t Group_id; /* group id of the user set for testfile */
114 char *test_desc; /* test specific message */
vapier37cf54a2007-04-13 20:58:17 +0000115
plars865695b2001-08-27 22:15:12 +0000116 /* Parse standard options given to run the test. */
117 msg = parse_opts(ac, av, (option_t *) NULL, NULL);
vapier37cf54a2007-04-13 20:58:17 +0000118 if (msg != (char *)NULL) {
plars865695b2001-08-27 22:15:12 +0000119 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
120 tst_exit();
121 }
122
123 /* Perform global setup for test */
124 setup();
125
126 /* Check looping state if -i option given */
127 for (lc = 0; TEST_LOOPING(lc); lc++) {
128 /* Reset Tst_count in case we are looping. */
129 Tst_count = 0;
130
131 for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
132 test_desc = Test_cases[ind].desc;
133 User_id = Test_cases[ind].user_id;
134 Group_id = Test_cases[ind].group_id;
135
vapier37cf54a2007-04-13 20:58:17 +0000136 /*
plars865695b2001-08-27 22:15:12 +0000137 * Call fchwon(2) with different user id and
138 * group id (numeric values) to set it on
139 * testfile.
vapier37cf54a2007-04-13 20:58:17 +0000140 */
plars865695b2001-08-27 22:15:12 +0000141 TEST(fchown(fildes, User_id, Group_id));
142
143 /* check return code of fchown(2) */
144 if (TEST_RETURN == -1) {
145 tst_resm(TFAIL,
146 "fchown() Fails to %s, errno=%d",
147 test_desc, TEST_ERRNO);
148 continue;
149 }
150 /*
151 * Perform functional verification if test
152 * executed without (-f) option.
153 */
154 if (STD_FUNCTIONAL_TEST) {
155 /*
vapier37cf54a2007-04-13 20:58:17 +0000156 * Get the testfile information using
plars865695b2001-08-27 22:15:12 +0000157 * fstat(2).
158 */
159 if (fstat(fildes, &stat_buf) < 0) {
160 tst_brkm(TFAIL, cleanup, "fstat(2) of "
161 "%s failed, errno:%d",
162 TESTFILE, TEST_ERRNO);
163 }
164 if (User_id == -1) {
165 User_id = Test_cases[ind - 1].user_id;
166 }
167 if (Group_id == -1) {
168 Group_id = Test_cases[ind - 1].group_id;
169 }
170
171 /*
172 * Check for expected Ownership ids
173 * set on testfile.
174 */
175 if ((stat_buf.st_uid != User_id) ||
176 (stat_buf.st_gid != Group_id)) {
177 tst_resm(TFAIL, "%s: Incorrect owner"
178 "ship set, Expected %d %d",
179 TESTFILE, User_id, Group_id);
180 } else {
vapier37cf54a2007-04-13 20:58:17 +0000181 tst_resm(TPASS,
182 "fchown() succeeds to %s of %s",
plars865695b2001-08-27 22:15:12 +0000183 test_desc, TESTFILE);
184 }
185 } else {
186 tst_resm(TPASS, "call succeeded");
187 }
188 }
vapier37cf54a2007-04-13 20:58:17 +0000189 } /* End for TEST_LOOPING */
plars865695b2001-08-27 22:15:12 +0000190
191 /* Call cleanup() to undo setup done for the test. */
192 cleanup();
193
vapier37cf54a2007-04-13 20:58:17 +0000194 /*NOTREACHED*/ return (0);
195} /* End main */
plars865695b2001-08-27 22:15:12 +0000196
197/*
198 * setup() - performs all ONE TIME setup for this test.
199 * Create a temporary directory and change directory to it.
200 * Create a test file under temporary directory.
201 */
vapier37cf54a2007-04-13 20:58:17 +0000202void setup()
plars865695b2001-08-27 22:15:12 +0000203{
plars865695b2001-08-27 22:15:12 +0000204
205 /* capture signals */
206 tst_sig(NOFORK, DEF_HANDLER, cleanup);
207
208 /* Check that the test process id is super/root */
209 if (geteuid() != 0) {
210 tst_brkm(TBROK, NULL, "Must be super/root for this test!");
211 tst_exit();
212 }
213
214 /* Pause if that option was specified */
215 TEST_PAUSE;
vapier37cf54a2007-04-13 20:58:17 +0000216
plars865695b2001-08-27 22:15:12 +0000217 /* make a temp directory and cd to it */
218 tst_tmpdir();
219
vapier37cf54a2007-04-13 20:58:17 +0000220 if ((fildes = open(TESTFILE, O_RDWR | O_CREAT, FILE_MODE)) == -1) {
plars865695b2001-08-27 22:15:12 +0000221 tst_brkm(TBROK, cleanup,
222 "open(%s, O_RDWR|O_CREAT, %o) Failed, errno=%d : %s",
223 TESTFILE, FILE_MODE, errno, strerror(errno));
224 }
225
vapier37cf54a2007-04-13 20:58:17 +0000226} /* End setup() */
plars865695b2001-08-27 22:15:12 +0000227
228/*
229 * cleanup() - performs all ONE TIME cleanup for this test at
230 * completion or premature exit.
231 * Close the testfile opened in the setup.
232 * Remove the test directory and testfile created in the setup.
233 */
vapier37cf54a2007-04-13 20:58:17 +0000234void cleanup()
plars865695b2001-08-27 22:15:12 +0000235{
236 /*
237 * print timing stats if that option was specified.
238 */
239 TEST_CLEANUP;
240
241 /* Close the testfile */
242 if (close(fildes) == -1) {
243 tst_brkm(TBROK, NULL, "close(%s) Failed, errno=%d : %s",
244 TESTFILE, errno, strerror(errno));
245 }
246
247 /* Remove tmp dir and all files in it */
248 tst_rmdir();
249
250 /* exit with return code appropriate for results */
251 tst_exit();
vapier37cf54a2007-04-13 20:58:17 +0000252} /* End cleanup() */