t_setgid.c revision 98122
1169691Skan/*
297403Sobrien * Copyright (c) 2001 Sendmail, Inc. and its suppliers.
397403Sobrien *	All rights reserved.
497403Sobrien *
597403Sobrien * By using this file, you agree to the terms and conditions set
697403Sobrien * forth in the LICENSE file which can be found at the top level of
797403Sobrien * the sendmail distribution.
897403Sobrien *
997403Sobrien */
1097403Sobrien
1197403Sobrien/*
1297403Sobrien**  This program checks to see if your version of setgid works.
1397403Sobrien**  Compile it, make it set-group-ID guest, and run it as yourself (NOT as
1497403Sobrien**  root and not as member of the group guest).
1597403Sobrien**
1697403Sobrien**  Compilation is trivial -- just "cc t_setgid.c".  Make it set-group-ID,
17169691Skan**  guest and then execute it as a non-root user.
1897403Sobrien*/
1997403Sobrien
2097403Sobrien#include <sys/types.h>
2197403Sobrien#include <unistd.h>
2297403Sobrien#include <stdio.h>
2397403Sobrien
2497403Sobrien#ifndef lint
2597403Sobrienstatic char id[] = "@(#)$Id: t_setgid.c,v 1.6 2001/09/23 03:35:41 ca Exp $";
2697403Sobrien#endif /* ! lint */
2797403Sobrien
2897403Sobrienstatic void
2997403Sobrienprintgids(str, r, e)
3097403Sobrien	char *str;
31132720Skan	gid_t r, e;
3297403Sobrien{
3397403Sobrien	printf("%s (should be %d/%d): r/egid=%d/%d\n", str, (int) r, (int) e,
3497403Sobrien	       (int) getgid(), (int) getegid());
35169691Skan}
3697403Sobrien
37169691Skanint
38107606Sobrienmain(argc, argv)
39169691Skan	int argc;
40169691Skan	char **argv;
41169691Skan{
42169691Skan	int fail = 0;
43169691Skan	int res;
44169691Skan	gid_t realgid = getgid();
45169691Skan	gid_t effgid = getegid();
46169691Skan
47169691Skan	printgids("initial gids", realgid, effgid);
48169691Skan
49169691Skan	if (effgid == realgid)
50169691Skan	{
51169691Skan		printf("SETUP ERROR: re-run set-group-ID guest\n");
52169691Skan		exit(1);
53169691Skan	}
54169691Skan
55169691Skan#if SM_CONF_SETREGID
56169691Skan	res = setregid(effgid, effgid);
57169691Skan#else /* SM_CONF_SETREGID */
58169691Skan	res = setgid(effgid);
5997403Sobrien#endif /* SM_CONF_SETREGID */
6097403Sobrien
6197403Sobrien	printf("setgid(%d)=%d %s\n", (int) effgid, res,
6297403Sobrien		res < 0 ? "failure" : "ok");
6397403Sobrien#if SM_CONF_SETREGID
6497403Sobrien	printgids("after setregid()", effgid, effgid);
6597403Sobrien#else /* SM_CONF_SETREGID */
6697403Sobrien	printgids("after setgid()", effgid, effgid);
6797403Sobrien#endif /* SM_CONF_SETREGID */
6897403Sobrien
69132720Skan	if (getegid() != effgid)
70132720Skan	{
7197403Sobrien		fail++;
7297403Sobrien		printf("MAYDAY!  Wrong effective gid\n");
73132720Skan	}
74132720Skan
7597403Sobrien	if (getgid() != effgid)
7697403Sobrien	{
7797403Sobrien		fail++;
78132720Skan		printf("MAYDAY!  Wrong real gid\n");
79132720Skan	}
8097403Sobrien
8197403Sobrien	/* do activity here */
8297403Sobrien	if (setgid(0) == 0)
83107606Sobrien	{
8497403Sobrien		fail++;
8597403Sobrien		printf("MAYDAY!  setgid(0) succeeded (should have failed)\n");
8697403Sobrien	}
87107606Sobrien	else
88107606Sobrien	{
89107606Sobrien		printf("setgid(0) failed (this is correct)\n");
9097403Sobrien	}
9197403Sobrien	printgids("after setgid(0)", effgid, effgid);
9297403Sobrien
93169691Skan	if (getegid() != effgid)
94169691Skan	{
95169691Skan		fail++;
96169691Skan		printf("MAYDAY!  Wrong effective gid\n");
97169691Skan	}
98132720Skan	if (getgid() != effgid)
99132720Skan	{
100169691Skan		fail++;
101169691Skan		printf("MAYDAY!  Wrong real gid\n");
102169691Skan	}
103169691Skan	printf("\n");
104169691Skan
105169691Skan	if (fail > 0)
106132720Skan	{
107169691Skan		printf("\nThis system cannot use %s to set the real gid to the effective gid\nand clear the saved gid.\n",
108132720Skan#if SM_CONF_SETREGID
10997403Sobrien			"setregid"
11097403Sobrien#else /* SM_CONF_SETREGID */
11197403Sobrien			"setgid"
11297403Sobrien#endif /* SM_CONF_SETREGID */
11397403Sobrien			);
11497403Sobrien		exit(1);
11597403Sobrien	}
11697403Sobrien
11797403Sobrien	printf("\nIt is possible to use setgid on this system\n");
11897403Sobrien	exit(0);
11997403Sobrien}
12097403Sobrien