t_dropgid.c revision 266692
1204076Spjd/*
2204076Spjd * Copyright (c) 2001 Proofpoint, Inc. and its suppliers.
3204076Spjd *	All rights reserved.
4204076Spjd *
5204076Spjd * By using this file, you agree to the terms and conditions set
6204076Spjd * forth in the LICENSE file which can be found at the top level of
7204076Spjd * the sendmail distribution.
8204076Spjd *
9204076Spjd */
10204076Spjd
11204076Spjd/*
12204076Spjd**  This program checks to see if your version of setgid works.
13204076Spjd**  Compile it, make it set-group-ID guest, and run it as yourself (NOT as
14204076Spjd**  root and not as member of the group guest).
15204076Spjd**
16204076Spjd**  Compilation is trivial -- just "cc t_dropgid.c".  Make it set-group-ID
17204076Spjd**  guest and then execute it as a non-root user.
18204076Spjd*/
19204076Spjd
20204076Spjd#include <sys/types.h>
21204076Spjd#include <unistd.h>
22204076Spjd#include <stdio.h>
23204076Spjd
24204076Spjd#ifndef lint
25204076Spjdstatic char id[] = "@(#)$Id: t_dropgid.c,v 1.7 2013-11-22 20:52:01 ca Exp $";
26204076Spjd#endif /* ! lint */
27204076Spjd
28204076Spjdstatic void
29204076Spjdprintgids(str, r, e)
30204076Spjd	char *str;
31204076Spjd	gid_t r, e;
32204076Spjd{
33204076Spjd	printf("%s (should be %d/%d): r/egid=%d/%d\n", str, (int) r, (int) e,
34204076Spjd	       (int) getgid(), (int) getegid());
35204076Spjd}
36204076Spjd
37204076Spjd/* define only one of these */
38204076Spjd#if HASSETEGID
39204076Spjd# define SETGIDCALL	"setegid"
40204076Spjd#endif /* HASSETEGID */
41204076Spjd#if HASSETREGID
42204076Spjd# define SETGIDCALL	"setregid"
43204076Spjd#endif /* HASSETREGID */
44204076Spjd#if HASSETRESGID
45204076Spjd# define SETGIDCALL	"setresgid"
46204076Spjd#endif /* HASSETRESGID */
47204076Spjd
48204076Spjd#ifndef SETGIDCALL
49204076Spjd#  define SETGIDCALL	"setgid"
50204076Spjd#endif /* ! SETGIDCALL */
51204076Spjd
52204076Spjdint
53204076Spjdmain(argc, argv)
54204076Spjd	int argc;
55204076Spjd	char **argv;
56204076Spjd{
57204076Spjd	int fail = 0;
58204076Spjd	int res;
59204076Spjd	gid_t realgid = getgid();
60204076Spjd	gid_t effgid = getegid();
61204076Spjd	char *prg = argv[0];
62204076Spjd
63204076Spjd	printgids("initial gids", realgid, effgid);
64204076Spjd
65204076Spjd	if (effgid == realgid)
66204076Spjd	{
67204076Spjd		printf("SETUP ERROR: re-run set-group-ID guest\n");
68204076Spjd		printf("Use chgrp(1) and chmod(1)\n");
69204076Spjd		printf("For example, do this as root ");
70204076Spjd		printf("(nobody is the name of a group in this example):\n");
71204076Spjd		printf("# chgrp nobody %s\n", prg);
72204076Spjd		printf("# chmod g+s nobody %s\n", prg);
73204076Spjd		exit(1);
74204076Spjd	}
75204076Spjd
76204076Spjd#if HASSETREGID
77204076Spjd	res = setregid(realgid, realgid);
78204076Spjd	printf("setregid(%d)=%d %s\n", (int) realgid, res,
79204076Spjd		res < 0 ? "failure" : "ok");
80204076Spjd	printgids("after setregid()", realgid, realgid);
81204076Spjd#endif /* HASSETREGID */
82204076Spjd#if HASSETRESGID
83204076Spjd	res = setresgid(realgid, realgid, realgid);
84204076Spjd	printf("setresgid(%d)=%d %s\n", (int) realgid, res,
85204076Spjd		res < 0 ? "failure" : "ok");
86204076Spjd	printgids("after setresgid()", realgid, realgid);
87204076Spjd#endif /* HASSETRESGID */
88204076Spjd#if HASSETEGID
89204076Spjd	res = setegid(realgid);
90204076Spjd	printf("setegid(%d)=%d %s\n", (int) realgid, res,
91204076Spjd		res < 0 ? "failure" : "ok");
92204076Spjd	printgids("after setegid()", realgid, realgid);
93204076Spjd#endif /* HASSETEGID */
94204076Spjd	res = setgid(realgid);
95204076Spjd	printf("setgid(%d)=%d %s\n", (int) realgid, res,
96204076Spjd		res < 0 ? "failure" : "ok");
97204076Spjd	printgids("after setgid()", realgid, realgid);
98204076Spjd
99204076Spjd	if (getegid() != realgid)
100204076Spjd	{
101204076Spjd		fail++;
102204076Spjd		printf("MAYDAY!  Wrong effective gid\n");
103204076Spjd	}
104204076Spjd
105204076Spjd	if (getgid() != realgid)
106204076Spjd	{
107204076Spjd		fail++;
108204076Spjd		printf("MAYDAY!  Wrong real gid\n");
109204076Spjd	}
110204076Spjd
111204076Spjd	/* do activity here */
112204076Spjd	if (setgid(effgid) == 0)
113204076Spjd	{
114204076Spjd		fail++;
115204076Spjd		printf("MAYDAY!  setgid(%d) succeeded (should have failed)\n",
116204076Spjd			effgid);
117204076Spjd	}
118204076Spjd	else
119204076Spjd	{
120204076Spjd		printf("setgid(%d) failed (this is correct)\n", effgid);
121204076Spjd	}
122204076Spjd	printgids("after setgid() to egid", realgid, realgid);
123204076Spjd
124204076Spjd	if (getegid() != realgid)
125204076Spjd	{
126204076Spjd		fail++;
127204076Spjd		printf("MAYDAY!  Wrong effective gid\n");
128204076Spjd	}
129214283Spjd	if (getgid() != realgid)
130217732Spjd	{
131204076Spjd		fail++;
132204076Spjd		printf("MAYDAY!  Wrong real gid\n");
133204076Spjd	}
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