1/*
2 * Copyright (c) 2001 Proofpoint, 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 setreuid works.
13**  Compile it, make it set-user-ID root, and run it as yourself (NOT as
14**  root).  If it won't compile or outputs any MAYDAY messages, don't
15**  define HASSETREUID in conf.h.
16**
17**  Compilation is trivial -- just "cc t_setreuid.c".  Make it set-user-ID,
18**  root and then execute it as a non-root user.
19*/
20
21#include <sys/types.h>
22#include <unistd.h>
23#include <stdio.h>
24
25#ifndef lint
26static char id[] = "@(#)$Id: t_setreuid.c,v 8.10 2013-11-22 20:52:01 ca Exp $";
27#endif /* ! lint */
28
29#ifdef __hpux
30# define setreuid(r, e)	setresuid(r, e, -1)
31#endif /* __hpux */
32
33static void
34printuids(str, r, e)
35	char *str;
36	uid_t r, e;
37{
38	printf("%s (should be %d/%d): r/euid=%d/%d\n", str, (int) r, (int) e,
39	       (int) getuid(), (int) geteuid());
40}
41
42int
43main(argc, argv)
44	int argc;
45	char **argv;
46{
47	int fail = 0;
48	uid_t realuid = getuid();
49
50	printuids("initial uids", realuid, 0);
51
52	if (geteuid() != 0)
53	{
54		printf("SETUP ERROR: re-run set-user-ID root\n");
55		exit(1);
56	}
57
58	if (getuid() == 0)
59	{
60		printf("SETUP ERROR: must be run by a non-root user\n");
61		exit(1);
62	}
63
64	if (setreuid(0, 1) < 0)
65	{
66		fail++;
67		printf("setreuid(0, 1) failure\n");
68	}
69	printuids("after setreuid(0, 1)", 0, 1);
70
71	if (getuid() != 0)
72	{
73		fail++;
74		printf("MAYDAY!  Wrong real uid\n");
75	}
76
77	if (geteuid() != 1)
78	{
79		fail++;
80		printf("MAYDAY!  Wrong effective uid\n");
81	}
82
83	/* do activity here */
84
85	if (setreuid(-1, 0) < 0)
86	{
87		fail++;
88		printf("setreuid(-1, 0) failure\n");
89	}
90	printuids("after setreuid(-1, 0)", 0, 0);
91	if (setreuid(realuid, 0) < 0)
92	{
93		fail++;
94		printf("setreuid(%d, 0) failure\n", (int) realuid);
95	}
96	printuids("after setreuid(realuid, 0)", realuid, 0);
97
98	if (geteuid() != 0)
99	{
100		fail++;
101		printf("MAYDAY!  Wrong effective uid\n");
102	}
103	if (getuid() != realuid)
104	{
105		fail++;
106		printf("MAYDAY!  Wrong real uid\n");
107	}
108	printf("\n");
109
110	if (setreuid(0, 2) < 0)
111	{
112		fail++;
113		printf("setreuid(0, 2) failure\n");
114	}
115	printuids("after setreuid(0, 2)", 0, 2);
116
117	if (geteuid() != 2)
118	{
119		fail++;
120		printf("MAYDAY!  Wrong effective uid\n");
121	}
122
123	if (getuid() != 0)
124	{
125		fail++;
126		printf("MAYDAY!  Wrong real uid\n");
127	}
128
129	/* do activity here */
130
131	if (setreuid(-1, 0) < 0)
132	{
133		fail++;
134		printf("setreuid(-1, 0) failure\n");
135	}
136	printuids("after setreuid(-1, 0)", 0, 0);
137	if (setreuid(realuid, 0) < 0)
138	{
139		fail++;
140		printf("setreuid(%d, 0) failure\n", (int) realuid);
141	}
142	printuids("after setreuid(realuid, 0)", realuid, 0);
143
144	if (geteuid() != 0)
145	{
146		fail++;
147		printf("MAYDAY!  Wrong effective uid\n");
148	}
149	if (getuid() != realuid)
150	{
151		fail++;
152		printf("MAYDAY!  Wrong real uid\n");
153	}
154
155	if (fail)
156	{
157		printf("\nThis system cannot use setreuid\n");
158		exit(1);
159	}
160
161	printf("\nIt is safe to define HASSETREUID on this system\n");
162	exit(0);
163}
164