190792Sgshapiro/*
2261363Sgshapiro * Copyright (c) 2001 Proofpoint, Inc. and its suppliers.
390792Sgshapiro *	All rights reserved.
490792Sgshapiro *
590792Sgshapiro * By using this file, you agree to the terms and conditions set
690792Sgshapiro * forth in the LICENSE file which can be found at the top level of
790792Sgshapiro * the sendmail distribution.
890792Sgshapiro *
990792Sgshapiro */
1090792Sgshapiro
1190792Sgshapiro/*
1290792Sgshapiro**  This program checks to see if your version of setgid works.
1390792Sgshapiro**  Compile it, make it set-group-ID guest, and run it as yourself (NOT as
1490792Sgshapiro**  root and not as member of the group guest).
1590792Sgshapiro**
1690792Sgshapiro**  Compilation is trivial -- just "cc t_dropgid.c".  Make it set-group-ID
1790792Sgshapiro**  guest and then execute it as a non-root user.
1890792Sgshapiro*/
1990792Sgshapiro
2090792Sgshapiro#include <sys/types.h>
2190792Sgshapiro#include <unistd.h>
2290792Sgshapiro#include <stdio.h>
2390792Sgshapiro
2490792Sgshapiro#ifndef lint
25266692Sgshapirostatic char id[] = "@(#)$Id: t_dropgid.c,v 1.7 2013-11-22 20:52:01 ca Exp $";
2690792Sgshapiro#endif /* ! lint */
2790792Sgshapiro
2890792Sgshapirostatic void
2990792Sgshapiroprintgids(str, r, e)
3090792Sgshapiro	char *str;
3190792Sgshapiro	gid_t r, e;
3290792Sgshapiro{
3390792Sgshapiro	printf("%s (should be %d/%d): r/egid=%d/%d\n", str, (int) r, (int) e,
3490792Sgshapiro	       (int) getgid(), (int) getegid());
3590792Sgshapiro}
3690792Sgshapiro
3790792Sgshapiro/* define only one of these */
3890792Sgshapiro#if HASSETEGID
3990792Sgshapiro# define SETGIDCALL	"setegid"
4090792Sgshapiro#endif /* HASSETEGID */
4190792Sgshapiro#if HASSETREGID
4290792Sgshapiro# define SETGIDCALL	"setregid"
4390792Sgshapiro#endif /* HASSETREGID */
4490792Sgshapiro#if HASSETRESGID
4590792Sgshapiro# define SETGIDCALL	"setresgid"
4690792Sgshapiro#endif /* HASSETRESGID */
4790792Sgshapiro
4890792Sgshapiro#ifndef SETGIDCALL
4990792Sgshapiro#  define SETGIDCALL	"setgid"
5090792Sgshapiro#endif /* ! SETGIDCALL */
5190792Sgshapiro
5290792Sgshapiroint
5390792Sgshapiromain(argc, argv)
5490792Sgshapiro	int argc;
5590792Sgshapiro	char **argv;
5690792Sgshapiro{
5790792Sgshapiro	int fail = 0;
5890792Sgshapiro	int res;
5990792Sgshapiro	gid_t realgid = getgid();
6090792Sgshapiro	gid_t effgid = getegid();
6190792Sgshapiro	char *prg = argv[0];
6290792Sgshapiro
6390792Sgshapiro	printgids("initial gids", realgid, effgid);
6490792Sgshapiro
6590792Sgshapiro	if (effgid == realgid)
6690792Sgshapiro	{
6790792Sgshapiro		printf("SETUP ERROR: re-run set-group-ID guest\n");
6890792Sgshapiro		printf("Use chgrp(1) and chmod(1)\n");
6990792Sgshapiro		printf("For example, do this as root ");
7090792Sgshapiro		printf("(nobody is the name of a group in this example):\n");
7190792Sgshapiro		printf("# chgrp nobody %s\n", prg);
7290792Sgshapiro		printf("# chmod g+s nobody %s\n", prg);
7390792Sgshapiro		exit(1);
7490792Sgshapiro	}
7590792Sgshapiro
7690792Sgshapiro#if HASSETREGID
7790792Sgshapiro	res = setregid(realgid, realgid);
7890792Sgshapiro	printf("setregid(%d)=%d %s\n", (int) realgid, res,
7990792Sgshapiro		res < 0 ? "failure" : "ok");
8090792Sgshapiro	printgids("after setregid()", realgid, realgid);
8190792Sgshapiro#endif /* HASSETREGID */
8290792Sgshapiro#if HASSETRESGID
8390792Sgshapiro	res = setresgid(realgid, realgid, realgid);
8490792Sgshapiro	printf("setresgid(%d)=%d %s\n", (int) realgid, res,
8590792Sgshapiro		res < 0 ? "failure" : "ok");
8690792Sgshapiro	printgids("after setresgid()", realgid, realgid);
8790792Sgshapiro#endif /* HASSETRESGID */
8890792Sgshapiro#if HASSETEGID
8990792Sgshapiro	res = setegid(realgid);
9090792Sgshapiro	printf("setegid(%d)=%d %s\n", (int) realgid, res,
9190792Sgshapiro		res < 0 ? "failure" : "ok");
9290792Sgshapiro	printgids("after setegid()", realgid, realgid);
9390792Sgshapiro#endif /* HASSETEGID */
9490792Sgshapiro	res = setgid(realgid);
9590792Sgshapiro	printf("setgid(%d)=%d %s\n", (int) realgid, res,
9690792Sgshapiro		res < 0 ? "failure" : "ok");
9790792Sgshapiro	printgids("after setgid()", realgid, realgid);
9890792Sgshapiro
9990792Sgshapiro	if (getegid() != realgid)
10090792Sgshapiro	{
10190792Sgshapiro		fail++;
10290792Sgshapiro		printf("MAYDAY!  Wrong effective gid\n");
10390792Sgshapiro	}
10490792Sgshapiro
10590792Sgshapiro	if (getgid() != realgid)
10690792Sgshapiro	{
10790792Sgshapiro		fail++;
10890792Sgshapiro		printf("MAYDAY!  Wrong real gid\n");
10990792Sgshapiro	}
11090792Sgshapiro
11190792Sgshapiro	/* do activity here */
11290792Sgshapiro	if (setgid(effgid) == 0)
11390792Sgshapiro	{
11490792Sgshapiro		fail++;
11590792Sgshapiro		printf("MAYDAY!  setgid(%d) succeeded (should have failed)\n",
11690792Sgshapiro			effgid);
11790792Sgshapiro	}
11890792Sgshapiro	else
11990792Sgshapiro	{
12090792Sgshapiro		printf("setgid(%d) failed (this is correct)\n", effgid);
12190792Sgshapiro	}
12290792Sgshapiro	printgids("after setgid() to egid", realgid, realgid);
12390792Sgshapiro
12490792Sgshapiro	if (getegid() != realgid)
12590792Sgshapiro	{
12690792Sgshapiro		fail++;
12790792Sgshapiro		printf("MAYDAY!  Wrong effective gid\n");
12890792Sgshapiro	}
12990792Sgshapiro	if (getgid() != realgid)
13090792Sgshapiro	{
13190792Sgshapiro		fail++;
13290792Sgshapiro		printf("MAYDAY!  Wrong real gid\n");
13390792Sgshapiro	}
13490792Sgshapiro	printf("\n");
13590792Sgshapiro
13690792Sgshapiro	if (fail > 0)
13790792Sgshapiro	{
13890792Sgshapiro		printf("\nThis system cannot use %s to give up set-group-ID rights\n",
13990792Sgshapiro		       SETGIDCALL);
14090792Sgshapiro#if !HASSETEGID
14190792Sgshapiro		printf("Maybe compile with -DHASSETEGID and try again\n");
14290792Sgshapiro#endif /* !HASSETEGID */
14390792Sgshapiro#if !HASSETREGID
14490792Sgshapiro		printf("Maybe compile with -DHASSETREGID and try again\n");
14590792Sgshapiro#endif /* !HASSETREGID */
14690792Sgshapiro#if !HASSETRESGID
14790792Sgshapiro		printf("Maybe compile with -DHASSETRESGID and try again\n");
14890792Sgshapiro#endif /* !HASSETRESGID */
14990792Sgshapiro		exit(1);
15090792Sgshapiro	}
15190792Sgshapiro
15290792Sgshapiro	printf("\nIt is possible to use %s on this system\n", SETGIDCALL);
15390792Sgshapiro	exit(0);
15490792Sgshapiro}
155