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
25 * Testcase to ensure that the setgid() system call sets errno to EPERM
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.
41 * 07/2001 Ported by Wayne Boyer
44 * Must be run as a nonroot user
51 TCID_DEFINE(setgid02
);
56 char nobody_uid
[] = "nobody";
57 char nobody_gid
[] = "nobody";
58 struct passwd
*ltpuser
;
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
);
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 */
91 if ((rootpwent
= getpwnam(root
)) == NULL
) {
92 tst_brkm(TBROK
, cleanup
, "getpwnam failed for user id "
96 if (!GID_SIZE_CHECK(rootpwent
->pw_gid
)) {
99 "gid for `%s' is too large for testing setgid16",
103 TEST(SETGID(rootpwent
->pw_gid
));
105 if (TEST_RETURN
!= -1) {
106 tst_resm(TFAIL
, "call succeeded unexpectedly");
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
);
116 tst_resm(TPASS
, "setgid returned EPERM");
126 * setup() - performs all ONE TIME setup for this test.
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
)) {
140 "gid for `%s' is too large for testing setgid16",
144 if (setgid(ltpuser
->pw_gid
) == -1) {
145 tst_resm(TINFO
, "setgid failed to "
146 "to set the effective gid to %d",
151 if (setuid(ltpuser
->pw_uid
) == -1) {
152 tst_resm(TINFO
, "setuid failed to "
153 "to set the effective uid to %d",
159 /* capture signals */
160 tst_sig(NOFORK
, DEF_HANDLER
, cleanup
);
162 /* Pause if that option was specified */
167 * cleanup() - performs all ONE TIME cleanup for this test at
168 * completion or premature exit.
174 * print timing stats if that option was specified.
175 * print errno log if that option was specified.
179 /* exit with return code appropriate for results */