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