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 setgid works.
13**  Compile it, make it set-group-ID guest, and run it as yourself (NOT as
14**  root and not as member of the group guest).
15**
16**  Compilation is trivial -- just "cc t_dropgid.c".  Make it set-group-ID
17**  guest and then execute it as a non-root user.
18*/
19
20#include <sys/types.h>
21#include <unistd.h>
22#include <stdio.h>
23
24#ifndef lint
25static char id[] = "@(#)$Id: t_dropgid.c,v 1.7 2013-11-22 20:52:01 ca Exp $";
26#endif /* ! lint */
27
28static void
29printgids(str, r, e)
30	char *str;
31	gid_t r, e;
32{
33	printf("%s (should be %d/%d): r/egid=%d/%d\n", str, (int) r, (int) e,
34	       (int) getgid(), (int) getegid());
35}
36
37/* define only one of these */
38#if HASSETEGID
39# define SETGIDCALL	"setegid"
40#endif /* HASSETEGID */
41#if HASSETREGID
42# define SETGIDCALL	"setregid"
43#endif /* HASSETREGID */
44#if HASSETRESGID
45# define SETGIDCALL	"setresgid"
46#endif /* HASSETRESGID */
47
48#ifndef SETGIDCALL
49#  define SETGIDCALL	"setgid"
50#endif /* ! SETGIDCALL */
51
52int
53main(argc, argv)
54	int argc;
55	char **argv;
56{
57	int fail = 0;
58	int res;
59	gid_t realgid = getgid();
60	gid_t effgid = getegid();
61	char *prg = argv[0];
62
63	printgids("initial gids", realgid, effgid);
64
65	if (effgid == realgid)
66	{
67		printf("SETUP ERROR: re-run set-group-ID guest\n");
68		printf("Use chgrp(1) and chmod(1)\n");
69		printf("For example, do this as root ");
70		printf("(nobody is the name of a group in this example):\n");
71		printf("# chgrp nobody %s\n", prg);
72		printf("# chmod g+s nobody %s\n", prg);
73		exit(1);
74	}
75
76#if HASSETREGID
77	res = setregid(realgid, realgid);
78	printf("setregid(%d)=%d %s\n", (int) realgid, res,
79		res < 0 ? "failure" : "ok");
80	printgids("after setregid()", realgid, realgid);
81#endif /* HASSETREGID */
82#if HASSETRESGID
83	res = setresgid(realgid, realgid, realgid);
84	printf("setresgid(%d)=%d %s\n", (int) realgid, res,
85		res < 0 ? "failure" : "ok");
86	printgids("after setresgid()", realgid, realgid);
87#endif /* HASSETRESGID */
88#if HASSETEGID
89	res = setegid(realgid);
90	printf("setegid(%d)=%d %s\n", (int) realgid, res,
91		res < 0 ? "failure" : "ok");
92	printgids("after setegid()", realgid, realgid);
93#endif /* HASSETEGID */
94	res = setgid(realgid);
95	printf("setgid(%d)=%d %s\n", (int) realgid, res,
96		res < 0 ? "failure" : "ok");
97	printgids("after setgid()", realgid, realgid);
98
99	if (getegid() != realgid)
100	{
101		fail++;
102		printf("MAYDAY!  Wrong effective gid\n");
103	}
104
105	if (getgid() != realgid)
106	{
107		fail++;
108		printf("MAYDAY!  Wrong real gid\n");
109	}
110
111	/* do activity here */
112	if (setgid(effgid) == 0)
113	{
114		fail++;
115		printf("MAYDAY!  setgid(%d) succeeded (should have failed)\n",
116			effgid);
117	}
118	else
119	{
120		printf("setgid(%d) failed (this is correct)\n", effgid);
121	}
122	printgids("after setgid() to egid", realgid, realgid);
123
124	if (getegid() != realgid)
125	{
126		fail++;
127		printf("MAYDAY!  Wrong effective gid\n");
128	}
129	if (getgid() != realgid)
130	{
131		fail++;
132		printf("MAYDAY!  Wrong real gid\n");
133	}
134	printf("\n");
135
136	if (fail > 0)
137	{
138		printf("\nThis system cannot use %s to give up set-group-ID rights\n",
139		       SETGIDCALL);
140#if !HASSETEGID
141		printf("Maybe compile with -DHASSETEGID and try again\n");
142#endif /* !HASSETEGID */
143#if !HASSETREGID
144		printf("Maybe compile with -DHASSETREGID and try again\n");
145#endif /* !HASSETREGID */
146#if !HASSETRESGID
147		printf("Maybe compile with -DHASSETRESGID and try again\n");
148#endif /* !HASSETRESGID */
149		exit(1);
150	}
151
152	printf("\nIt is possible to use %s on this system\n", SETGIDCALL);
153	exit(0);
154}
155