190792Sgshapiro/*
2261194Sgshapiro * 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_setgid.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
25266527Sgshapirostatic char id[] = "@(#)$Id: t_setgid.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
3790792Sgshapiroint
3890792Sgshapiromain(argc, argv)
3990792Sgshapiro	int argc;
4090792Sgshapiro	char **argv;
4190792Sgshapiro{
4290792Sgshapiro	int fail = 0;
4390792Sgshapiro	int res;
4490792Sgshapiro	gid_t realgid = getgid();
4590792Sgshapiro	gid_t effgid = getegid();
4690792Sgshapiro
4790792Sgshapiro	printgids("initial gids", realgid, effgid);
4890792Sgshapiro
4990792Sgshapiro	if (effgid == realgid)
5090792Sgshapiro	{
5190792Sgshapiro		printf("SETUP ERROR: re-run set-group-ID guest\n");
5290792Sgshapiro		exit(1);
5390792Sgshapiro	}
5490792Sgshapiro
5590792Sgshapiro#if SM_CONF_SETREGID
5690792Sgshapiro	res = setregid(effgid, effgid);
5790792Sgshapiro#else /* SM_CONF_SETREGID */
5890792Sgshapiro	res = setgid(effgid);
5990792Sgshapiro#endif /* SM_CONF_SETREGID */
6090792Sgshapiro
6190792Sgshapiro	printf("setgid(%d)=%d %s\n", (int) effgid, res,
6290792Sgshapiro		res < 0 ? "failure" : "ok");
6390792Sgshapiro#if SM_CONF_SETREGID
6490792Sgshapiro	printgids("after setregid()", effgid, effgid);
6590792Sgshapiro#else /* SM_CONF_SETREGID */
6690792Sgshapiro	printgids("after setgid()", effgid, effgid);
6790792Sgshapiro#endif /* SM_CONF_SETREGID */
6890792Sgshapiro
6990792Sgshapiro	if (getegid() != effgid)
7090792Sgshapiro	{
7190792Sgshapiro		fail++;
7290792Sgshapiro		printf("MAYDAY!  Wrong effective gid\n");
7390792Sgshapiro	}
7490792Sgshapiro
7590792Sgshapiro	if (getgid() != effgid)
7690792Sgshapiro	{
7790792Sgshapiro		fail++;
7890792Sgshapiro		printf("MAYDAY!  Wrong real gid\n");
7990792Sgshapiro	}
8090792Sgshapiro
8190792Sgshapiro	/* do activity here */
8290792Sgshapiro	if (setgid(0) == 0)
8390792Sgshapiro	{
8490792Sgshapiro		fail++;
8590792Sgshapiro		printf("MAYDAY!  setgid(0) succeeded (should have failed)\n");
8690792Sgshapiro	}
8790792Sgshapiro	else
8890792Sgshapiro	{
8990792Sgshapiro		printf("setgid(0) failed (this is correct)\n");
9090792Sgshapiro	}
9190792Sgshapiro	printgids("after setgid(0)", effgid, effgid);
9290792Sgshapiro
9390792Sgshapiro	if (getegid() != effgid)
9490792Sgshapiro	{
9590792Sgshapiro		fail++;
9690792Sgshapiro		printf("MAYDAY!  Wrong effective gid\n");
9790792Sgshapiro	}
9890792Sgshapiro	if (getgid() != effgid)
9990792Sgshapiro	{
10090792Sgshapiro		fail++;
10190792Sgshapiro		printf("MAYDAY!  Wrong real gid\n");
10290792Sgshapiro	}
10390792Sgshapiro	printf("\n");
10490792Sgshapiro
10590792Sgshapiro	if (fail > 0)
10690792Sgshapiro	{
10790792Sgshapiro		printf("\nThis system cannot use %s to set the real gid to the effective gid\nand clear the saved gid.\n",
10890792Sgshapiro#if SM_CONF_SETREGID
10990792Sgshapiro			"setregid"
11090792Sgshapiro#else /* SM_CONF_SETREGID */
11190792Sgshapiro			"setgid"
11290792Sgshapiro#endif /* SM_CONF_SETREGID */
11390792Sgshapiro			);
11490792Sgshapiro		exit(1);
11590792Sgshapiro	}
11690792Sgshapiro
11790792Sgshapiro	printf("\nIt is possible to use setgid on this system\n");
11890792Sgshapiro	exit(0);
11990792Sgshapiro}
120