xref: /freebsd/contrib/sendmail/test/t_setuid.c (revision 39beb93c)
1 /*
2  * Copyright (c) 2001 Sendmail, Inc. and its suppliers.
3  *	All rights reserved.
4  *
5  * By using this file, you agree to the terms and conditions set
6  * forth in the LICENSE file which can be found at the top level of
7  * the sendmail distribution.
8  *
9  */
10 
11 /*
12 **  This program checks to see if your version of setuid works.
13 **  Compile it, make it set-user-ID root, and run it as yourself (NOT as
14 **  root).
15 **
16 **	NOTE:  This should work everywhere, but Linux has the ability
17 **	to use the undocumented setcap() call to make this break.
18 **
19 **  Compilation is trivial -- just "cc t_setuid.c".  Make it set-user-ID,
20 **  root and then execute it as a non-root user.
21 */
22 
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <stdio.h>
26 
27 #ifndef lint
28 static char id[] = "@(#)$Id: t_setuid.c,v 8.7 2001/09/23 03:35:41 ca Exp $";
29 #endif /* ! lint */
30 
31 static void
32 printuids(str, r, e)
33 	char *str;
34 	uid_t r, e;
35 {
36 	printf("%s (should be %d/%d): r/euid=%d/%d\n", str, (int) r, (int) e,
37 	       (int) getuid(), (int) geteuid());
38 }
39 
40 int
41 main(argc, argv)
42 	int argc;
43 	char **argv;
44 {
45 	int fail = 0;
46 	uid_t realuid = getuid();
47 
48 	printuids("initial uids", realuid, 0);
49 
50 	if (geteuid() != 0)
51 	{
52 		printf("SETUP ERROR: re-run set-user-ID root\n");
53 		exit(1);
54 	}
55 
56 	if (getuid() == 0)
57 	{
58 		printf("SETUP ERROR: must be run by a non-root user\n");
59 		exit(1);
60 	}
61 
62 	if (setuid(1) < 0)
63 		printf("setuid(1) failure\n");
64 	printuids("after setuid(1)", 1, 1);
65 
66 	if (geteuid() != 1)
67 	{
68 		fail++;
69 		printf("MAYDAY!  Wrong effective uid\n");
70 	}
71 
72 	if (getuid() != 1)
73 	{
74 		fail++;
75 		printf("MAYDAY!  Wrong real uid\n");
76 	}
77 
78 
79 	/* do activity here */
80 	if (setuid(0) == 0)
81 	{
82 		fail++;
83 		printf("MAYDAY!  setuid(0) succeeded (should have failed)\n");
84 	}
85 	else
86 	{
87 		printf("setuid(0) failed (this is correct)\n");
88 	}
89 	printuids("after setuid(0)", 1, 1);
90 
91 	if (geteuid() != 1)
92 	{
93 		fail++;
94 		printf("MAYDAY!  Wrong effective uid\n");
95 	}
96 	if (getuid() != 1)
97 	{
98 		fail++;
99 		printf("MAYDAY!  Wrong real uid\n");
100 	}
101 	printf("\n");
102 
103 	if (fail)
104 	{
105 		printf("\nThis system cannot use setuid (maybe use setreuid)\n");
106 		exit(1);
107 	}
108 
109 	printf("\nIt is safe to use setuid on this system\n");
110 	exit(0);
111 }
112