1 /* 2 * Copyright (c) Dan Kegel 2003 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 /* 20 * Test Name: setegid01 21 * 22 * Test Description: 23 * Verify that setegid does not modify the saved gid or real gid. 24 */ 25 26 #define _GNU_SOURCE 1 27 #include <pwd.h> 28 #include <sys/types.h> 29 #include <stdio.h> 30 #include <unistd.h> 31 #include <errno.h> 32 #include "test.h" 33 #include "safe_macros.h" 34 35 char *TCID = "setegid01"; 36 int TST_TOTAL = 1; 37 static void setup(void); 38 static void setegid_verify(void); 39 static void cleanup(void); 40 41 static gid_t nobody_gid; 42 43 int main(int argc, char **argv) 44 { 45 int lc; 46 47 tst_parse_opts(argc, argv, NULL, NULL); 48 49 setup(); 50 51 for (lc = 0; TEST_LOOPING(lc); lc++) { 52 tst_count = 0; 53 setegid_verify(); 54 } 55 56 cleanup(); 57 tst_exit(); 58 } 59 60 static void setup(void) 61 { 62 struct passwd *nobody; 63 64 tst_require_root(); 65 66 tst_sig(NOFORK, DEF_HANDLER, cleanup); 67 68 TEST_PAUSE; 69 70 nobody = SAFE_GETPWNAM(cleanup, "nobody"); 71 72 nobody_gid = nobody->pw_gid; 73 } 74 75 static void setegid_verify(void) 76 { 77 gid_t cur_rgid, cur_egid, cur_sgid; 78 gid_t orig_rgid, orig_egid, orig_sgid; 79 80 SAFE_GETRESGID(cleanup, &orig_rgid, &orig_egid, &orig_sgid); 81 tst_resm(TINFO, "getresgid reports rgid %d, egid %d, sgid %d", 82 orig_rgid, orig_egid, orig_sgid); 83 84 tst_resm(TINFO, "calling setegid(nobody_gid %d)", nobody_gid); 85 SAFE_SETEGID(cleanup, nobody_gid); 86 87 SAFE_GETRESGID(cleanup, &cur_rgid, &cur_egid, &cur_sgid); 88 tst_resm(TINFO, "getresgid reports rgid %d, egid %d, sgid %d", cur_rgid, 89 cur_egid, cur_sgid); 90 91 /* make sure it at least does what its name says */ 92 if (nobody_gid != cur_egid) { 93 tst_resm(TFAIL, "setegid() failed to change the effective gid"); 94 return; 95 } 96 97 /* SUSv3 says the real group ID and saved set-gid must 98 * remain unchanged by setgid. See 99 * http://www.opengroup.org/onlinepubs/007904975/functions/setegid.html 100 */ 101 if (orig_sgid != cur_sgid) { 102 tst_resm(TFAIL, "setegid() changed the saved set-gid"); 103 return; 104 } 105 if (orig_rgid != cur_rgid) { 106 tst_resm(TFAIL, "setegid() changed the real gid"); 107 return; 108 } 109 110 SAFE_SETEGID(cleanup, orig_egid); 111 112 SAFE_GETRESGID(cleanup, &cur_rgid, &cur_egid, &orig_sgid); 113 114 if (orig_egid != cur_egid) { 115 tst_resm(TFAIL, "setegid() failed to reset effective gid back"); 116 return; 117 } 118 119 tst_resm(TPASS, "setegid() passed functional test"); 120 } 121 122 static void cleanup(void) 123 { 124 } 125