t_setuid.c revision 261363
1284990Scy/* 2284990Scy * Copyright (c) 2001 Proofpoint, Inc. and its suppliers. 3284990Scy * All rights reserved. 4284990Scy * 5289997Sglebius * By using this file, you agree to the terms and conditions set 6284990Scy * forth in the LICENSE file which can be found at the top level of 7284990Scy * the sendmail distribution. 8284990Scy * 9284990Scy */ 10284990Scy 11284990Scy/* 12284990Scy** This program checks to see if your version of setuid works. 13284990Scy** Compile it, make it set-user-ID root, and run it as yourself (NOT as 14284990Scy** root). 15284990Scy** 16284990Scy** NOTE: This should work everywhere, but Linux has the ability 17284990Scy** to use the undocumented setcap() call to make this break. 18289997Sglebius** 19289997Sglebius** Compilation is trivial -- just "cc t_setuid.c". Make it set-user-ID, 20284990Scy** root and then execute it as a non-root user. 21284990Scy*/ 22284990Scy 23284990Scy#include <sys/types.h> 24289997Sglebius#include <unistd.h> 25289997Sglebius#include <stdio.h> 26284990Scy 27289997Sglebius#ifndef lint 28284990Scystatic char id[] = "@(#)$Id: t_setuid.c,v 8.8 2013/11/22 20:52:01 ca Exp $"; 29284990Scy#endif /* ! lint */ 30284990Scy 31289997Sglebiusstatic void 32289997Sglebiusprintuids(str, r, e) 33284990Scy char *str; 34284990Scy uid_t r, e; 35289997Sglebius{ 36284990Scy printf("%s (should be %d/%d): r/euid=%d/%d\n", str, (int) r, (int) e, 37284990Scy (int) getuid(), (int) geteuid()); 38284990Scy} 39284990Scy 40284990Scyint 41284990Scymain(argc, argv) 42284990Scy int argc; 43284990Scy char **argv; 44284990Scy{ 45284990Scy int fail = 0; 46284990Scy uid_t realuid = getuid(); 47284990Scy 48284990Scy printuids("initial uids", realuid, 0); 49284990Scy 50289997Sglebius if (geteuid() != 0) 51284990Scy { 52284990Scy printf("SETUP ERROR: re-run set-user-ID root\n"); 53284990Scy exit(1); 54284990Scy } 55284990Scy 56284990Scy if (getuid() == 0) 57284990Scy { 58289997Sglebius printf("SETUP ERROR: must be run by a non-root user\n"); 59284990Scy exit(1); 60284990Scy } 61284990Scy 62284990Scy if (setuid(1) < 0) 63284990Scy printf("setuid(1) failure\n"); 64284990Scy printuids("after setuid(1)", 1, 1); 65284990Scy 66289997Sglebius if (geteuid() != 1) 67284990Scy { 68284990Scy fail++; 69284990Scy printf("MAYDAY! Wrong effective uid\n"); 70284990Scy } 71284990Scy 72284990Scy if (getuid() != 1) 73284990Scy { 74289997Sglebius fail++; 75284990Scy printf("MAYDAY! Wrong real uid\n"); 76284990Scy } 77284990Scy 78289997Sglebius 79284990Scy /* do activity here */ 80284990Scy if (setuid(0) == 0) 81284990Scy { 82284990Scy fail++; 83284990Scy printf("MAYDAY! setuid(0) succeeded (should have failed)\n"); 84289997Sglebius } 85284990Scy else 86289997Sglebius { 87289997Sglebius printf("setuid(0) failed (this is correct)\n"); 88289997Sglebius } 89289997Sglebius printuids("after setuid(0)", 1, 1); 90289997Sglebius 91284990Scy if (geteuid() != 1) 92284990Scy { 93289997Sglebius fail++; 94284990Scy printf("MAYDAY! Wrong effective uid\n"); 95284990Scy } 96284990Scy if (getuid() != 1) 97284990Scy { 98284990Scy fail++; 99284990Scy printf("MAYDAY! Wrong real uid\n"); 100289997Sglebius } 101284990Scy printf("\n"); 102284990Scy 103284990Scy if (fail) 104284990Scy { 105284990Scy printf("\nThis system cannot use setuid (maybe use setreuid)\n"); 106284990Scy exit(1); 107284990Scy } 108284990Scy 109289997Sglebius printf("\nIt is safe to use setuid on this system\n"); 110284990Scy exit(0); 111289997Sglebius} 112284990Scy