Home | History | Annotate | Download | only in setreuid
      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  * Ported by John George
     20  */
     21 
     22 /*
     23  * Test setreuid() when executed by an unpriviledged user.
     24  */
     25 
     26 #include <errno.h>
     27 #include <pwd.h>
     28 #include <stdlib.h>
     29 
     30 #include "test.h"
     31 #include "safe_macros.h"
     32 #include "compat_16.h"
     33 
     34 #define FAILED  1
     35 
     36 TCID_DEFINE(setreuid03);
     37 
     38 static int fail = -1;
     39 static int pass;
     40 static uid_t neg_one = -1;
     41 
     42 static struct passwd nobody, bin, root;
     43 
     44 /*
     45  * The following structure contains all test data.  Each structure in the array
     46  * is used for a separate test.  The tests are executed in the for loop below.
     47  */
     48 
     49 static struct test_data_t {
     50 	uid_t *real_uid;
     51 	uid_t *eff_uid;
     52 	int *exp_ret;
     53 	struct passwd *exp_real_usr;
     54 	struct passwd *exp_eff_usr;
     55 	char *test_msg;
     56 } test_data[] = {
     57 	{
     58 	&nobody.pw_uid, &nobody.pw_uid, &pass, &nobody, &nobody,
     59 		    "After setreuid(nobody, nobody),"}, {
     60 	&neg_one, &nobody.pw_uid, &pass, &nobody, &nobody,
     61 		    "After setreuid(-1, nobody),"}, {
     62 	&nobody.pw_uid, &neg_one, &pass, &nobody, &nobody,
     63 		    "After setreuid(nobody, -1),"}, {
     64 	&neg_one, &neg_one, &pass, &nobody, &nobody, "After setreuid(-1, -1),"},
     65 	{
     66 	&neg_one, &root.pw_uid, &fail, &nobody, &nobody,
     67 		    "After setreuid(-1, root),"}, {
     68 	&root.pw_uid, &neg_one, &fail, &nobody, &nobody,
     69 		    "After setreuid(root, -1),"}, {
     70 	&root.pw_uid, &root.pw_uid, &fail, &nobody, &nobody,
     71 		    "After setreuid(root, root),"}, {
     72 	&root.pw_uid, &nobody.pw_uid, &fail, &nobody, &nobody,
     73 		    "After setreuid(root, nobody),"}, {
     74 	&root.pw_uid, &bin.pw_uid, &fail, &nobody, &nobody,
     75 		    "After setreuid(root, nobody),"}, {
     76 	&bin.pw_uid, &root.pw_uid, &fail, &nobody, &nobody,
     77 		    "After setreuid(bin, root),"}, {
     78 	&bin.pw_uid, &neg_one, &fail, &nobody, &nobody,
     79 		    "After setreuid(bin, -1),"}, {
     80 	&bin.pw_uid, &bin.pw_uid, &fail, &nobody, &nobody,
     81 		    "After setreuid(bin, bin,),"}, {
     82 	&bin.pw_uid, &nobody.pw_uid, &fail, &nobody, &nobody,
     83 		    "After setreuid(bin, nobody),"}, {
     84 	&nobody.pw_uid, &bin.pw_uid, &fail, &nobody, &nobody,
     85 		    "After setreuid(nobody, bin),"},};
     86 
     87 int TST_TOTAL = ARRAY_SIZE(test_data);
     88 
     89 static void setup(void);
     90 static void cleanup(void);
     91 static void uid_verify(struct passwd *, struct passwd *, char *);
     92 
     93 int main(int ac, char **av)
     94 {
     95 	int lc;
     96 
     97 	tst_parse_opts(ac, av, NULL, NULL);
     98 
     99 	setup();
    100 
    101 	for (lc = 0; TEST_LOOPING(lc); lc++) {
    102 		int i;
    103 
    104 		tst_count = 0;
    105 
    106 		for (i = 0; i < TST_TOTAL; i++) {
    107 
    108 			/* Set the real or effective user id */
    109 			TEST(SETREUID(cleanup, *test_data[i].real_uid,
    110 				      *test_data[i].eff_uid));
    111 
    112 			if (TEST_RETURN == *test_data[i].exp_ret) {
    113 				if (TEST_RETURN == neg_one) {
    114 					if (TEST_ERRNO != EPERM) {
    115 						tst_resm(TFAIL,
    116 							 "setreuid(%d, %d) "
    117 							 "did not set errno "
    118 							 "value as expected.",
    119 							 *test_data[i].real_uid,
    120 							 *test_data[i].eff_uid);
    121 						continue;
    122 					}
    123 					tst_resm(TPASS, "setreuid(%d, %d) "
    124 						 "failed as expected.",
    125 						 *test_data[i].real_uid,
    126 						 *test_data[i].eff_uid);
    127 				} else {
    128 					tst_resm(TPASS, "setreuid(%d, %d) "
    129 						 "succeeded as expected.",
    130 						 *test_data[i].real_uid,
    131 						 *test_data[i].eff_uid);
    132 				}
    133 			} else {
    134 				tst_resm(TFAIL, "setreuid(%d, %d) "
    135 					 "did not return as expected.",
    136 					 *test_data[i].real_uid,
    137 					 *test_data[i].eff_uid);
    138 			}
    139 
    140 			if (TEST_RETURN == -1) {
    141 			}
    142 			uid_verify(test_data[i].exp_real_usr,
    143 				   test_data[i].exp_eff_usr,
    144 				   test_data[i].test_msg);
    145 		}
    146 	}
    147 
    148 	cleanup();
    149 	tst_exit();
    150 }
    151 
    152 static void setup(void)
    153 {
    154 	tst_require_root();
    155 
    156 	tst_sig(FORK, DEF_HANDLER, cleanup);
    157 
    158 	if (getpwnam("nobody") == NULL)
    159 		tst_brkm(TBROK, NULL, "nobody must be a valid user.");
    160 
    161 	if (getpwnam("bin") == NULL)
    162 		tst_brkm(TBROK, NULL, "bin must be a valid user.");
    163 
    164 	root = *(getpwnam("root"));
    165 	UID16_CHECK(root.pw_uid, setreuid, cleanup);
    166 
    167 	nobody = *(getpwnam("nobody"));
    168 	UID16_CHECK(nobody.pw_uid, setreuid, cleanup);
    169 
    170 	bin = *(getpwnam("bin"));
    171 	UID16_CHECK(bin.pw_uid, setreuid, cleanup);
    172 
    173 	SAFE_SETUID(NULL, nobody.pw_uid);
    174 
    175 	TEST_PAUSE;
    176 }
    177 
    178 static void cleanup(void)
    179 {
    180 }
    181 
    182 static void uid_verify(struct passwd *ru, struct passwd *eu, char *when)
    183 {
    184 	if ((getuid() != ru->pw_uid) || (geteuid() != eu->pw_uid)) {
    185 		tst_resm(TFAIL, "ERROR: %s real uid = %d; effective uid = %d",
    186 			 when, getuid(), geteuid());
    187 		tst_resm(TINFO, "Expected: real uid = %d; effective uid = %d",
    188 			 ru->pw_uid, eu->pw_uid);
    189 	}
    190 }
    191