xref: /original-bsd/lib/libc/gen/initgroups.c (revision 7a8f01dc)
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.6 (Berkeley) 06/01/90";
10 #endif /* LIBC_SCCS and not lint */
11 
12 /*
13  * initgroups
14  */
15 #include <stdio.h>
16 #include <sys/param.h>
17 #include <grp.h>
18 
19 struct group *getgrent();
20 
21 initgroups(uname, agroup)
22 	char *uname;
23 	int agroup;
24 {
25 	int groups[NGROUPS], ngroups = 0;
26 	register struct group *grp;
27 	register int i;
28 
29 	/*
30 	 * If installing primary group, duplicate it;
31 	 * the first element of groups is the effective gid
32 	 * and will be overwritten when a setgid file is executed.
33 	 */
34 	if (agroup >= 0) {
35 		groups[ngroups++] = agroup;
36 		groups[ngroups++] = agroup;
37 	}
38 	setgrent();
39 	while (grp = getgrent()) {
40 		if (grp->gr_gid == agroup)
41 			continue;
42 		for (i = 0; grp->gr_mem[i]; i++)
43 			if (!strcmp(grp->gr_mem[i], uname)) {
44 				if (ngroups == NGROUPS) {
45 fprintf(stderr, "initgroups: %s is in too many groups\n", uname);
46 					goto toomany;
47 				}
48 				groups[ngroups++] = grp->gr_gid;
49 			}
50 	}
51 toomany:
52 	endgrent();
53 	if (setgroups(ngroups, groups) < 0) {
54 		perror("setgroups");
55 		return (-1);
56 	}
57 	return (0);
58 }
59