Merge branch 'vendor/BINUTILS221'
[dragonfly.git] / contrib / opie / libmissing / initgroups.c
1 /* initgroups.c: Replacement for the initgroups() function.
2
3 %%% portions-copyright-cmetz
4 Portions of this software are Copyright 1996 by Craig Metz, All Rights
5 Reserved. The Inner Net License Version 2 applies to these portions of
6 the software.
7 You should have received a copy of the license with this software. If
8 you didn't get a copy, you may request one from <license@inner.net>.
9
10         History:
11
12         Modified by cmetz for OPIE 2.2. Removed useless string.
13               Ifdef around headers. Use FUNCTION declarations.
14               Not everyone has multiple groups. Work around
15               lack of NGROUPS.
16         Originally from 4.3BSD Net/2.
17 */
18 /*
19  * Copyright (c) 1983 Regents of the University of California.
20  * All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the above copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *      This product includes software developed by the University of
33  *      California, Berkeley and its contributors.
34  * 4. Neither the name of the University nor the names of its contributors
35  *    may be used to endorse or promote products derived from this software
36  *    without specific prior written permission.
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  */
50
51 /*
52  * initgroups
53  */
54 #include "opie_cfg.h"
55
56 #if HAVE_SYS_PARAM_H
57 #include <sys/param.h>
58 #endif /* HAVE_SYS_PARAM_H */
59 #include <stdio.h>
60 #if HAVE_STRING_H
61 #include <string.h>
62 #endif /* HAVE_STRING */
63 #if HAVE_UNISTD_H
64 #include <unistd.h>
65 #endif /* HAVE_UNISTD_H */
66 #include <grp.h>
67
68 #include "opie.h"
69
70 struct group *getgrent();
71
72 int initgroups FUNCTION((uname, agroup), const char *uname AND int agroup)
73 {
74 #if HAVE_SETGROUPS && HAVE_GETGROUPS
75 #if NGROUPS
76         int groups[NGROUPS];
77 #else /* NGROUPS */
78 #define STARTING_NGROUPS 32
79         int groups[STARTING_NGROUPS];
80 #endif /* NGROUPS */
81         int ngroups;
82         register struct group *grp;
83         register int i;
84
85         /*
86          * If installing primary group, duplicate it;
87          * the first element of groups is the effective gid
88          * and will be overwritten when a setgid file is executed.
89          */
90         if (agroup >= 0) {
91                 groups[ngroups++] = agroup;
92                 groups[ngroups++] = agroup;
93         }
94         setgrent();
95         while (grp = getgrent()) {
96                 if (grp->gr_gid == agroup)
97                         continue;
98                 for (i = 0; grp->gr_mem[i]; i++)
99                         if (!strcmp(grp->gr_mem[i], uname)) {
100 #if NGROUPS
101                                 if (ngroups == NGROUPS) {
102 #else /* NGROUPS */
103                                 if (ngroups == STARTING_NGROUPS) {
104 #endif /* NGROUPS */
105 fprintf(stderr, "initgroups: %s is in too many groups\n", uname);
106                                         goto toomany;
107                                 }
108                                 groups[ngroups++] = grp->gr_gid;
109                         }
110         }
111 toomany:
112         endgrent();
113 #if NGROUPS
114         if (setgroups(ngroups, groups) < 0) {
115                 perror("setgroups");
116                 return (-1);
117         }
118 #else /* NGROUPS */
119         ngroups++;
120         do { 
121           if ((i = setgroups(--ngroups, groups) < 0) && (i != EINVAL)) {
122                 perror("setgroups");
123                 return (-1);
124           }
125         } while ((i < 0) && (ngroups > 0));
126 #endif /* NGROUPS */
127 #endif /* HAVE_SETGROUPS && HAVE_GETGROUPS */
128         return (0);
129 }