Imported Upstream version 20080930
[ltp-debian.git] / testcases / kernel / syscalls / setgid / setgid02.c
blob8fa513afea485df0a34d6dfa1f7ac1f382bfce16
1 /*
3 * Copyright (c) International Business Machines Corp., 2001
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.
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.
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
21 * NAME
22 * setgid02.c
24 * DESCRIPTION
25 * Testcase to ensure that the setgid() system call sets errno to EPERM
27 * ALGORITHM
28 * Call setgid() to set the gid to that of root. Run this test as
29 * ltpuser1, and expect to get EPERM
31 * USAGE: <for command-line>
32 * setgid02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
33 * where, -c n : Run n copies concurrently.
34 * -e : Turn on errno logging.
35 * -i n : Execute test n times.
36 * -I x : Execute test for x seconds.
37 * -P x : Pause for x seconds between iterations.
38 * -t : Turn on syscall timing.
40 * HISTORY
41 * 07/2001 Ported by Wayne Boyer
43 * RESTRICTIONS
44 * Must be run as a nonroot user
46 #include <pwd.h>
47 #include <errno.h>
48 #include <test.h>
49 #include <usctest.h>
51 TCID_DEFINE(setgid02);
52 int TST_TOTAL = 1;
53 extern int Tst_count;
55 char root[] = "root";
56 char nobody_uid[] = "nobody";
57 char nobody_gid[] = "nobody";
58 struct passwd *ltpuser;
61 void setup(void);
62 void cleanup(void);
64 #include "compat_16.h"
66 int exp_enos[] = {EPERM, 0};
68 int main(int ac, char **av)
70 struct passwd *getpwnam(), *rootpwent;
72 int lc; /* loop counter */
73 char *msg; /* message returned by parse_opts */
75 /* parse standard options */
76 if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
77 tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
78 /*NOTREACHED*/
81 setup();
83 TEST_EXP_ENOS(exp_enos);
85 /* check looping state if -i option is given */
86 for (lc = 0; TEST_LOOPING(lc); lc++) {
87 /* reset Tst_count in case we are looping */
88 Tst_count = 0;
91 if ((rootpwent = getpwnam(root)) == NULL) {
92 tst_brkm(TBROK, cleanup, "getpwnam failed for user id "
93 "%s", root);
96 if (!GID_SIZE_CHECK(rootpwent->pw_gid)) {
97 tst_brkm(TBROK,
98 cleanup,
99 "gid for `%s' is too large for testing setgid16",
100 root);
103 TEST(SETGID(rootpwent->pw_gid));
105 if (TEST_RETURN != -1) {
106 tst_resm(TFAIL, "call succeeded unexpectedly");
107 continue;
110 TEST_ERROR_LOG(TEST_ERRNO);
112 if (TEST_ERRNO != EPERM) {
113 tst_resm(TFAIL, "setgid set invalid errno, expected: "
114 "EPERM, got: %d\n", TEST_ERRNO);
115 } else {
116 tst_resm(TPASS, "setgid returned EPERM");
119 cleanup();
121 /*NOTREACHED*/
122 return(0);
126 * setup() - performs all ONE TIME setup for this test.
128 void
129 setup()
131 /* Switch to nobody user for correct error code collection */
132 if (geteuid() != 0) {
133 tst_brkm(TBROK, tst_exit, "Test must be run as root");
135 ltpuser = getpwnam(nobody_uid);
137 if (!GID_SIZE_CHECK(ltpuser->pw_gid)) {
138 tst_brkm(TBROK,
139 cleanup,
140 "gid for `%s' is too large for testing setgid16",
141 nobody_gid);
144 if (setgid(ltpuser->pw_gid) == -1) {
145 tst_resm(TINFO, "setgid failed to "
146 "to set the effective gid to %d",
147 ltpuser->pw_gid);
148 perror("setgid");
151 if (setuid(ltpuser->pw_uid) == -1) {
152 tst_resm(TINFO, "setuid failed to "
153 "to set the effective uid to %d",
154 ltpuser->pw_uid);
155 perror("setuid");
159 /* capture signals */
160 tst_sig(NOFORK, DEF_HANDLER, cleanup);
162 /* Pause if that option was specified */
163 TEST_PAUSE;
167 * cleanup() - performs all ONE TIME cleanup for this test at
168 * completion or premature exit.
170 void
171 cleanup()
174 * print timing stats if that option was specified.
175 * print errno log if that option was specified.
177 TEST_CLEANUP;
179 /* exit with return code appropriate for results */
180 tst_exit();