164562Sgshapiro/* 2261363Sgshapiro * Copyright (c) 2001 Proofpoint, Inc. and its suppliers. 390792Sgshapiro * All rights reserved. 490792Sgshapiro * 590792Sgshapiro * By using this file, you agree to the terms and conditions set 690792Sgshapiro * forth in the LICENSE file which can be found at the top level of 790792Sgshapiro * the sendmail distribution. 890792Sgshapiro * 990792Sgshapiro */ 1090792Sgshapiro 1190792Sgshapiro/* 1264562Sgshapiro** This program checks to see if your version of setuid works. 1390792Sgshapiro** Compile it, make it set-user-ID root, and run it as yourself (NOT as 1464562Sgshapiro** root). 1564562Sgshapiro** 1664562Sgshapiro** NOTE: This should work everywhere, but Linux has the ability 1764562Sgshapiro** to use the undocumented setcap() call to make this break. 1864562Sgshapiro** 1990792Sgshapiro** Compilation is trivial -- just "cc t_setuid.c". Make it set-user-ID, 2064562Sgshapiro** root and then execute it as a non-root user. 2164562Sgshapiro*/ 2264562Sgshapiro 2364562Sgshapiro#include <sys/types.h> 2464562Sgshapiro#include <unistd.h> 2564562Sgshapiro#include <stdio.h> 2664562Sgshapiro 2764562Sgshapiro#ifndef lint 28266692Sgshapirostatic char id[] = "@(#)$Id: t_setuid.c,v 8.8 2013-11-22 20:52:01 ca Exp $"; 2964562Sgshapiro#endif /* ! lint */ 3064562Sgshapiro 3164562Sgshapirostatic void 3264562Sgshapiroprintuids(str, r, e) 3364562Sgshapiro char *str; 3490792Sgshapiro uid_t r, e; 3564562Sgshapiro{ 3690792Sgshapiro printf("%s (should be %d/%d): r/euid=%d/%d\n", str, (int) r, (int) e, 3790792Sgshapiro (int) getuid(), (int) geteuid()); 3864562Sgshapiro} 3964562Sgshapiro 4064562Sgshapiroint 4164562Sgshapiromain(argc, argv) 4264562Sgshapiro int argc; 4364562Sgshapiro char **argv; 4464562Sgshapiro{ 4564562Sgshapiro int fail = 0; 4664562Sgshapiro uid_t realuid = getuid(); 4764562Sgshapiro 4864562Sgshapiro printuids("initial uids", realuid, 0); 4964562Sgshapiro 5064562Sgshapiro if (geteuid() != 0) 5164562Sgshapiro { 5290792Sgshapiro printf("SETUP ERROR: re-run set-user-ID root\n"); 5364562Sgshapiro exit(1); 5464562Sgshapiro } 5564562Sgshapiro 5664562Sgshapiro if (getuid() == 0) 5764562Sgshapiro { 5864562Sgshapiro printf("SETUP ERROR: must be run by a non-root user\n"); 5964562Sgshapiro exit(1); 6064562Sgshapiro } 6164562Sgshapiro 6264562Sgshapiro if (setuid(1) < 0) 6364562Sgshapiro printf("setuid(1) failure\n"); 6464562Sgshapiro printuids("after setuid(1)", 1, 1); 6564562Sgshapiro 6664562Sgshapiro if (geteuid() != 1) 6764562Sgshapiro { 6864562Sgshapiro fail++; 6964562Sgshapiro printf("MAYDAY! Wrong effective uid\n"); 7064562Sgshapiro } 7164562Sgshapiro 7264562Sgshapiro if (getuid() != 1) 7364562Sgshapiro { 7464562Sgshapiro fail++; 7564562Sgshapiro printf("MAYDAY! Wrong real uid\n"); 7664562Sgshapiro } 7764562Sgshapiro 7864562Sgshapiro 7964562Sgshapiro /* do activity here */ 8064562Sgshapiro if (setuid(0) == 0) 8164562Sgshapiro { 8264562Sgshapiro fail++; 8364562Sgshapiro printf("MAYDAY! setuid(0) succeeded (should have failed)\n"); 8464562Sgshapiro } 8564562Sgshapiro else 8664562Sgshapiro { 8764562Sgshapiro printf("setuid(0) failed (this is correct)\n"); 8864562Sgshapiro } 8964562Sgshapiro printuids("after setuid(0)", 1, 1); 9064562Sgshapiro 9164562Sgshapiro if (geteuid() != 1) 9264562Sgshapiro { 9364562Sgshapiro fail++; 9464562Sgshapiro printf("MAYDAY! Wrong effective uid\n"); 9564562Sgshapiro } 9664562Sgshapiro if (getuid() != 1) 9764562Sgshapiro { 9864562Sgshapiro fail++; 9964562Sgshapiro printf("MAYDAY! Wrong real uid\n"); 10064562Sgshapiro } 10164562Sgshapiro printf("\n"); 10264562Sgshapiro 10364562Sgshapiro if (fail) 10464562Sgshapiro { 10564562Sgshapiro printf("\nThis system cannot use setuid (maybe use setreuid)\n"); 10664562Sgshapiro exit(1); 10764562Sgshapiro } 10864562Sgshapiro 10964562Sgshapiro printf("\nIt is safe to use setuid on this system\n"); 11064562Sgshapiro exit(0); 11164562Sgshapiro} 112