1 /*
2  * Copyright (C) 2004, 2005, 2008  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1998, 1999, 2001, 2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <port_before.h>
19 #if !defined(_REENTRANT) || !defined(DO_PTHREADS)
20 	static int getnetgrent_r_not_required = 0;
21 #else
22 #include <errno.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include <sys/types.h>
26 #include <netinet/in.h>
27 #include <netdb.h>
28 #include <stdlib.h>
29 #include <port_after.h>
30 
31 #ifdef NGR_R_RETURN
32 #ifndef NGR_R_PRIVATE
33 #define NGR_R_PRIVATE 0
34 #endif
35 
36 static NGR_R_RETURN
37 copy_protoent(NGR_R_CONST char **, NGR_R_CONST char **, NGR_R_CONST char **,
38 	      const char *, const char *, const char *, NGR_R_COPY_ARGS);
39 
40 NGR_R_RETURN
innetgr_r(const char * netgroup,const char * host,const char * user,const char * domain)41 innetgr_r(const char *netgroup, const char *host, const char *user,
42 	  const char *domain) {
43 	char *ng, *ho, *us, *dom;
44 
45 	DE_CONST(netgroup, ng);
46 	DE_CONST(host, ho);
47 	DE_CONST(user, us);
48 	DE_CONST(domain, dom);
49 
50 	return (innetgr(ng, ho, us, dom));
51 }
52 
53 /*%
54  *	These assume a single context is in operation per thread.
55  *	If this is not the case we will need to call irs directly
56  *	rather than through the base functions.
57  */
58 
59 NGR_R_RETURN
getnetgrent_r(NGR_R_CONST char ** machinep,NGR_R_CONST char ** userp,NGR_R_CONST char ** domainp,NGR_R_ARGS)60 getnetgrent_r(NGR_R_CONST char **machinep, NGR_R_CONST char **userp,
61 	      NGR_R_CONST char **domainp, NGR_R_ARGS)
62 {
63 	NGR_R_CONST char *mp, *up, *dp;
64 	int res = getnetgrent(&mp, &up, &dp);
65 
66 	if (res != 1)
67 		return (res);
68 
69 	return (copy_protoent(machinep, userp, domainp,
70 				mp, up, dp, NGR_R_COPY));
71 }
72 
73 #if NGR_R_PRIVATE == 2
74 struct private {
75 	char *buf;
76 };
77 
78 #endif
79 NGR_R_SET_RETURN
80 #ifdef NGR_R_SET_ARGS
setnetgrent_r(NGR_R_SET_CONST char * netgroup,NGR_R_SET_ARGS)81 setnetgrent_r(NGR_R_SET_CONST char *netgroup, NGR_R_SET_ARGS)
82 #else
83 setnetgrent_r(NGR_R_SET_CONST char *netgroup)
84 #endif
85 {
86 #if NGR_R_PRIVATE == 2
87 	struct private *p;
88 #endif
89 	char *tmp;
90 #if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0
91 	UNUSED(buf);
92 	UNUSED(buflen);
93 #endif
94 
95 	DE_CONST(netgroup, tmp);
96 	setnetgrent(tmp);
97 
98 #if NGR_R_PRIVATE == 1
99 	*buf = NULL;
100 #elif NGR_R_PRIVATE == 2
101 	*buf = p = malloc(sizeof(struct private));
102 	if (p == NULL)
103 #ifdef NGR_R_SET_RESULT
104 		return (NGR_R_BAD);
105 #else
106 		return;
107 #endif
108 	p->buf = NULL;
109 #endif
110 #ifdef NGR_R_SET_RESULT
111 	return (NGR_R_SET_RESULT);
112 #endif
113 }
114 
115 NGR_R_END_RETURN
116 #ifdef NGR_R_END_ARGS
endnetgrent_r(NGR_R_END_ARGS)117 endnetgrent_r(NGR_R_END_ARGS)
118 #else
119 endnetgrent_r(void)
120 #endif
121 {
122 #if NGR_R_PRIVATE == 2
123 	struct private *p = buf;
124 #endif
125 #if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0
126 	UNUSED(buf);
127 	UNUSED(buflen);
128 #endif
129 
130 	endnetgrent();
131 #if NGR_R_PRIVATE == 1
132 	if (*buf != NULL)
133 		free(*buf);
134 	*buf = NULL;
135 #elif NGR_R_PRIVATE == 2
136 	if (p->buf != NULL)
137 		free(p->buf);
138 	free(p);
139 #endif
140 	NGR_R_END_RESULT(NGR_R_OK);
141 }
142 
143 /* Private */
144 
145 static int
copy_protoent(NGR_R_CONST char ** machinep,NGR_R_CONST char ** userp,NGR_R_CONST char ** domainp,const char * mp,const char * up,const char * dp,NGR_R_COPY_ARGS)146 copy_protoent(NGR_R_CONST char **machinep, NGR_R_CONST char **userp,
147 	      NGR_R_CONST char **domainp, const char *mp, const char *up,
148 	      const char *dp, NGR_R_COPY_ARGS)
149 {
150 #if NGR_R_PRIVATE == 2
151 	struct private *p = buf;
152 #endif
153 	char *cp;
154 	int n;
155 	int len;
156 
157 	/* Find out the amount of space required to store the answer. */
158 	len = 0;
159 	if (mp != NULL) len += strlen(mp) + 1;
160 	if (up != NULL) len += strlen(up) + 1;
161 	if (dp != NULL) len += strlen(dp) + 1;
162 
163 #if NGR_R_PRIVATE == 1
164 	if (*buf != NULL)
165 		free(*buf);
166 	*buf = malloc(len);
167 	if (*buf == NULL)
168 		return(NGR_R_BAD);
169 	cp = *buf;
170 #elif NGR_R_PRIVATE == 2
171 	if (p->buf)
172 		free(p->buf);
173 	p->buf = malloc(len);
174 	if (p->buf == NULL)
175 		return(NGR_R_BAD);
176 	cp = p->buf;
177 #else
178 	if (len > (int)buflen) {
179 		errno = ERANGE;
180 		return (NGR_R_BAD);
181 	}
182 	cp = buf;
183 #endif
184 
185 	if (mp != NULL) {
186 		n = strlen(mp) + 1;
187 		strcpy(cp, mp);
188 		*machinep = cp;
189 		cp += n;
190 	} else
191 		*machinep = NULL;
192 
193 	if (up != NULL) {
194 		n = strlen(up) + 1;
195 		strcpy(cp, up);
196 		*userp = cp;
197 		cp += n;
198 	} else
199 		*userp = NULL;
200 
201 	if (dp != NULL) {
202 		n = strlen(dp) + 1;
203 		strcpy(cp, dp);
204 		*domainp = cp;
205 		cp += n;
206 	} else
207 		*domainp = NULL;
208 
209 	return (NGR_R_OK);
210 }
211 #else /* NGR_R_RETURN */
212 	static int getnetgrent_r_unknown_system = 0;
213 #endif /* NGR_R_RETURN */
214 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
215 /*! \file */
216