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