t_dropgid.c revision 266692
1204076Spjd/* 2204076Spjd * Copyright (c) 2001 Proofpoint, Inc. and its suppliers. 3204076Spjd * All rights reserved. 4204076Spjd * 5204076Spjd * By using this file, you agree to the terms and conditions set 6204076Spjd * forth in the LICENSE file which can be found at the top level of 7204076Spjd * the sendmail distribution. 8204076Spjd * 9204076Spjd */ 10204076Spjd 11204076Spjd/* 12204076Spjd** This program checks to see if your version of setgid works. 13204076Spjd** Compile it, make it set-group-ID guest, and run it as yourself (NOT as 14204076Spjd** root and not as member of the group guest). 15204076Spjd** 16204076Spjd** Compilation is trivial -- just "cc t_dropgid.c". Make it set-group-ID 17204076Spjd** guest and then execute it as a non-root user. 18204076Spjd*/ 19204076Spjd 20204076Spjd#include <sys/types.h> 21204076Spjd#include <unistd.h> 22204076Spjd#include <stdio.h> 23204076Spjd 24204076Spjd#ifndef lint 25204076Spjdstatic char id[] = "@(#)$Id: t_dropgid.c,v 1.7 2013-11-22 20:52:01 ca Exp $"; 26204076Spjd#endif /* ! lint */ 27204076Spjd 28204076Spjdstatic void 29204076Spjdprintgids(str, r, e) 30204076Spjd char *str; 31204076Spjd gid_t r, e; 32204076Spjd{ 33204076Spjd printf("%s (should be %d/%d): r/egid=%d/%d\n", str, (int) r, (int) e, 34204076Spjd (int) getgid(), (int) getegid()); 35204076Spjd} 36204076Spjd 37204076Spjd/* define only one of these */ 38204076Spjd#if HASSETEGID 39204076Spjd# define SETGIDCALL "setegid" 40204076Spjd#endif /* HASSETEGID */ 41204076Spjd#if HASSETREGID 42204076Spjd# define SETGIDCALL "setregid" 43204076Spjd#endif /* HASSETREGID */ 44204076Spjd#if HASSETRESGID 45204076Spjd# define SETGIDCALL "setresgid" 46204076Spjd#endif /* HASSETRESGID */ 47204076Spjd 48204076Spjd#ifndef SETGIDCALL 49204076Spjd# define SETGIDCALL "setgid" 50204076Spjd#endif /* ! SETGIDCALL */ 51204076Spjd 52204076Spjdint 53204076Spjdmain(argc, argv) 54204076Spjd int argc; 55204076Spjd char **argv; 56204076Spjd{ 57204076Spjd int fail = 0; 58204076Spjd int res; 59204076Spjd gid_t realgid = getgid(); 60204076Spjd gid_t effgid = getegid(); 61204076Spjd char *prg = argv[0]; 62204076Spjd 63204076Spjd printgids("initial gids", realgid, effgid); 64204076Spjd 65204076Spjd if (effgid == realgid) 66204076Spjd { 67204076Spjd printf("SETUP ERROR: re-run set-group-ID guest\n"); 68204076Spjd printf("Use chgrp(1) and chmod(1)\n"); 69204076Spjd printf("For example, do this as root "); 70204076Spjd printf("(nobody is the name of a group in this example):\n"); 71204076Spjd printf("# chgrp nobody %s\n", prg); 72204076Spjd printf("# chmod g+s nobody %s\n", prg); 73204076Spjd exit(1); 74204076Spjd } 75204076Spjd 76204076Spjd#if HASSETREGID 77204076Spjd res = setregid(realgid, realgid); 78204076Spjd printf("setregid(%d)=%d %s\n", (int) realgid, res, 79204076Spjd res < 0 ? "failure" : "ok"); 80204076Spjd printgids("after setregid()", realgid, realgid); 81204076Spjd#endif /* HASSETREGID */ 82204076Spjd#if HASSETRESGID 83204076Spjd res = setresgid(realgid, realgid, realgid); 84204076Spjd printf("setresgid(%d)=%d %s\n", (int) realgid, res, 85204076Spjd res < 0 ? "failure" : "ok"); 86204076Spjd printgids("after setresgid()", realgid, realgid); 87204076Spjd#endif /* HASSETRESGID */ 88204076Spjd#if HASSETEGID 89204076Spjd res = setegid(realgid); 90204076Spjd printf("setegid(%d)=%d %s\n", (int) realgid, res, 91204076Spjd res < 0 ? "failure" : "ok"); 92204076Spjd printgids("after setegid()", realgid, realgid); 93204076Spjd#endif /* HASSETEGID */ 94204076Spjd res = setgid(realgid); 95204076Spjd printf("setgid(%d)=%d %s\n", (int) realgid, res, 96204076Spjd res < 0 ? "failure" : "ok"); 97204076Spjd printgids("after setgid()", realgid, realgid); 98204076Spjd 99204076Spjd if (getegid() != realgid) 100204076Spjd { 101204076Spjd fail++; 102204076Spjd printf("MAYDAY! Wrong effective gid\n"); 103204076Spjd } 104204076Spjd 105204076Spjd if (getgid() != realgid) 106204076Spjd { 107204076Spjd fail++; 108204076Spjd printf("MAYDAY! Wrong real gid\n"); 109204076Spjd } 110204076Spjd 111204076Spjd /* do activity here */ 112204076Spjd if (setgid(effgid) == 0) 113204076Spjd { 114204076Spjd fail++; 115204076Spjd printf("MAYDAY! setgid(%d) succeeded (should have failed)\n", 116204076Spjd effgid); 117204076Spjd } 118204076Spjd else 119204076Spjd { 120204076Spjd printf("setgid(%d) failed (this is correct)\n", effgid); 121204076Spjd } 122204076Spjd printgids("after setgid() to egid", realgid, realgid); 123204076Spjd 124204076Spjd if (getegid() != realgid) 125204076Spjd { 126204076Spjd fail++; 127204076Spjd printf("MAYDAY! Wrong effective gid\n"); 128204076Spjd } 129214283Spjd if (getgid() != realgid) 130217732Spjd { 131204076Spjd fail++; 132204076Spjd printf("MAYDAY! Wrong real gid\n"); 133204076Spjd } 134 printf("\n"); 135 136 if (fail > 0) 137 { 138 printf("\nThis system cannot use %s to give up set-group-ID rights\n", 139 SETGIDCALL); 140#if !HASSETEGID 141 printf("Maybe compile with -DHASSETEGID and try again\n"); 142#endif /* !HASSETEGID */ 143#if !HASSETREGID 144 printf("Maybe compile with -DHASSETREGID and try again\n"); 145#endif /* !HASSETREGID */ 146#if !HASSETRESGID 147 printf("Maybe compile with -DHASSETRESGID and try again\n"); 148#endif /* !HASSETRESGID */ 149 exit(1); 150 } 151 152 printf("\nIt is possible to use %s on this system\n", SETGIDCALL); 153 exit(0); 154} 155