xref: /original-bsd/lib/libc/gen/initgroups.c (revision 95407d66)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)initgroups.c	5.7 (Berkeley) 02/23/91";
10 #endif /* LIBC_SCCS and not lint */
11 
12 /*
13  * initgroups
14  */
15 #include <sys/param.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <grp.h>
20 
21 struct group *getgrent();
22 
23 int
24 initgroups(uname, agroup)
25 	const char *uname;
26 	int agroup;
27 {
28 	int groups[NGROUPS], ngroups = 0;
29 	register struct group *grp;
30 	register int i;
31 
32 	/*
33 	 * If installing primary group, duplicate it;
34 	 * the first element of groups is the effective gid
35 	 * and will be overwritten when a setgid file is executed.
36 	 */
37 	if (agroup >= 0) {
38 		groups[ngroups++] = agroup;
39 		groups[ngroups++] = agroup;
40 	}
41 	setgrent();
42 	while (grp = getgrent()) {
43 		if (grp->gr_gid == agroup)
44 			continue;
45 		for (i = 0; grp->gr_mem[i]; i++)
46 			if (!strcmp(grp->gr_mem[i], uname)) {
47 				if (ngroups == NGROUPS) {
48 fprintf(stderr, "initgroups: %s is in too many groups\n", uname);
49 					goto toomany;
50 				}
51 				groups[ngroups++] = grp->gr_gid;
52 			}
53 	}
54 toomany:
55 	endgrent();
56 	if (setgroups(ngroups, groups) < 0) {
57 		perror("setgroups");
58 		return (-1);
59 	}
60 	return (0);
61 }
62