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 * Test Name: chown05
22 *
23 * Test Description:
24 * Verify that, chown(2) succeeds to change the owner and group of a file
25 * specified by path to any numeric owner(uid)/group(gid) values when invoked
26 * by super-user.
27 *
28 * Expected Result:
29 * chown(2) should return 0 and the ownership set on the file should match
30 * the numeric values contained in owner and group respectively.
31 *
32 * 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,
44 * Verify the Functionality of system call
45 * 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>
54 * chown05 [-c n] [-e] [-f] [-i n] [-I x] [-P x] [-t]
55 * where, -c n : Run n copies concurrently.
56 * -e : Turn on errno logging.
57 * -f : Turn off functionality Testing.
58 * -i n : Execute test n times.
59 * -I x : Execute test for x seconds.
60 * -P x : Pause for x seconds between iterations.
61 * -t : Turn on syscall timing.
62 *
63 * HISTORY
64 * 07/2001 Ported by Wayne Boyer
65 *
66 * RESTRICTIONS:
67 * This test should be run by 'super-user' (root) only.
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 "compat_16.h"
80
81 #define FILE_MODE (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
82 #define TESTFILE "testfile"
83
84 TCID_DEFINE(chown05);
85
86 struct test_case_t {
87 uid_t user_id;
88 gid_t group_id;
89 } test_cases[] = {
90 {
91 700, 701}, {
92 702, -1}, {
93 703, 701}, {
94 -1, 704}, {
95 703, 705},};
96
97 int TST_TOTAL = ARRAY_SIZE(test_cases);
98
99 void setup(); /* setup function for the test */
100 void cleanup(); /* cleanup function for the test */
101
main(int ac,char ** av)102 int main(int ac, char **av)
103 {
104 struct stat stat_buf; /* stat(2) struct contents */
105 int lc;
106 int i;
107 uid_t user_id; /* user id of the user set for testfile */
108 gid_t group_id; /* group id of the user set for testfile */
109
110 tst_parse_opts(ac, av, NULL, NULL);
111
112 setup();
113
114 for (lc = 0; TEST_LOOPING(lc); lc++) {
115
116 tst_count = 0;
117
118 for (i = 0; i < TST_TOTAL; i++) {
119 user_id = test_cases[i].user_id;
120 group_id = test_cases[i].group_id;
121
122 TEST(CHOWN(cleanup, TESTFILE, user_id, group_id));
123
124 if (TEST_RETURN == -1) {
125 tst_resm(TFAIL | TTERRNO, "chown failed");
126 continue;
127 }
128 if (stat(TESTFILE, &stat_buf) == -1)
129 tst_brkm(TFAIL, cleanup, "stat failed");
130 if (user_id == -1)
131 user_id = test_cases[i - 1].user_id;
132 if (group_id == -1)
133 group_id = test_cases[i - 1].group_id;
134
135 if (stat_buf.st_uid != user_id ||
136 stat_buf.st_gid != group_id)
137 tst_resm(TFAIL, "%s: incorrect "
138 "ownership set, Expected %d "
139 "%d", TESTFILE, user_id,
140 group_id);
141 else
142 tst_resm(TPASS, "chown succeeded");
143 }
144 }
145
146 cleanup();
147 tst_exit();
148 }
149
setup(void)150 void setup(void)
151 {
152 int fd;
153
154 tst_sig(NOFORK, DEF_HANDLER, cleanup);
155
156 tst_require_root();
157
158 TEST_PAUSE;
159
160 tst_tmpdir();
161
162 if ((fd = open(TESTFILE, O_RDWR | O_CREAT, FILE_MODE)) == -1)
163 tst_brkm(TBROK | TERRNO, cleanup, "opening %s failed",
164 TESTFILE);
165 if (close(fd) == -1)
166 tst_brkm(TBROK, cleanup, "closing %s failed", TESTFILE);
167
168 }
169
cleanup(void)170 void cleanup(void)
171 {
172 tst_rmdir();
173 }
174