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