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 #if defined(LIBC_SCCS) && !defined(lint)
19 static const char rcsid[] = "$Id: getnetgrent_r.c,v 1.14 2008/11/14 02:36:51 marka Exp $";
20 #endif /* LIBC_SCCS and not lint */
21
22 #include <port_before.h>
23 #if !defined(_REENTRANT) || !defined(DO_PTHREADS)
24 static int getnetgrent_r_not_required = 0;
25 #else
26 #include <errno.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <sys/types.h>
30 #include <netinet/in.h>
31 #include <netdb.h>
32 #include <stdlib.h>
33 #include <port_after.h>
34
35 #ifdef NGR_R_RETURN
36 #ifndef NGR_R_PRIVATE
37 #define NGR_R_PRIVATE 0
38 #endif
39
40 static NGR_R_RETURN
41 copy_protoent(NGR_R_CONST char **, NGR_R_CONST char **, NGR_R_CONST char **,
42 const char *, const char *, const char *, NGR_R_COPY_ARGS);
43
44 NGR_R_RETURN
innetgr_r(const char * netgroup,const char * host,const char * user,const char * domain)45 innetgr_r(const char *netgroup, const char *host, const char *user,
46 const char *domain) {
47 char *ng, *ho, *us, *dom;
48
49 DE_CONST(netgroup, ng);
50 DE_CONST(host, ho);
51 DE_CONST(user, us);
52 DE_CONST(domain, dom);
53
54 return (innetgr(ng, ho, us, dom));
55 }
56
57 /*%
58 * These assume a single context is in operation per thread.
59 * If this is not the case we will need to call irs directly
60 * rather than through the base functions.
61 */
62
63 NGR_R_RETURN
getnetgrent_r(NGR_R_CONST char ** machinep,NGR_R_CONST char ** userp,NGR_R_CONST char ** domainp,NGR_R_ARGS)64 getnetgrent_r(NGR_R_CONST char **machinep, NGR_R_CONST char **userp,
65 NGR_R_CONST char **domainp, NGR_R_ARGS)
66 {
67 NGR_R_CONST char *mp, *up, *dp;
68 int res = getnetgrent(&mp, &up, &dp);
69
70 if (res != 1)
71 return (res);
72
73 return (copy_protoent(machinep, userp, domainp,
74 mp, up, dp, NGR_R_COPY));
75 }
76
77 #if NGR_R_PRIVATE == 2
78 struct private {
79 char *buf;
80 };
81
82 #endif
83 NGR_R_SET_RETURN
84 #ifdef NGR_R_SET_ARGS
setnetgrent_r(NGR_R_SET_CONST char * netgroup,NGR_R_SET_ARGS)85 setnetgrent_r(NGR_R_SET_CONST char *netgroup, NGR_R_SET_ARGS)
86 #else
87 setnetgrent_r(NGR_R_SET_CONST char *netgroup)
88 #endif
89 {
90 #if NGR_R_PRIVATE == 2
91 struct private *p;
92 #endif
93 char *tmp;
94 #if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0
95 UNUSED(buf);
96 UNUSED(buflen);
97 #endif
98
99 DE_CONST(netgroup, tmp);
100 setnetgrent(tmp);
101
102 #if NGR_R_PRIVATE == 1
103 *buf = NULL;
104 #elif NGR_R_PRIVATE == 2
105 *buf = p = malloc(sizeof(struct private));
106 if (p == NULL)
107 #ifdef NGR_R_SET_RESULT
108 return (NGR_R_BAD);
109 #else
110 return;
111 #endif
112 p->buf = NULL;
113 #endif
114 #ifdef NGR_R_SET_RESULT
115 return (NGR_R_SET_RESULT);
116 #endif
117 }
118
119 NGR_R_END_RETURN
120 #ifdef NGR_R_END_ARGS
endnetgrent_r(NGR_R_END_ARGS)121 endnetgrent_r(NGR_R_END_ARGS)
122 #else
123 endnetgrent_r(void)
124 #endif
125 {
126 #if NGR_R_PRIVATE == 2
127 struct private *p = buf;
128 #endif
129 #if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0
130 UNUSED(buf);
131 UNUSED(buflen);
132 #endif
133
134 endnetgrent();
135 #if NGR_R_PRIVATE == 1
136 if (*buf != NULL)
137 free(*buf);
138 *buf = NULL;
139 #elif NGR_R_PRIVATE == 2
140 if (p->buf != NULL)
141 free(p->buf);
142 free(p);
143 #endif
144 NGR_R_END_RESULT(NGR_R_OK);
145 }
146
147 /* Private */
148
149 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)150 copy_protoent(NGR_R_CONST char **machinep, NGR_R_CONST char **userp,
151 NGR_R_CONST char **domainp, const char *mp, const char *up,
152 const char *dp, NGR_R_COPY_ARGS)
153 {
154 #if NGR_R_PRIVATE == 2
155 struct private *p = buf;
156 #endif
157 char *cp;
158 int n;
159 int len;
160
161 /* Find out the amount of space required to store the answer. */
162 len = 0;
163 if (mp != NULL) len += strlen(mp) + 1;
164 if (up != NULL) len += strlen(up) + 1;
165 if (dp != NULL) len += strlen(dp) + 1;
166
167 #if NGR_R_PRIVATE == 1
168 if (*buf != NULL)
169 free(*buf);
170 *buf = malloc(len);
171 if (*buf == NULL)
172 return(NGR_R_BAD);
173 cp = *buf;
174 #elif NGR_R_PRIVATE == 2
175 if (p->buf)
176 free(p->buf);
177 p->buf = malloc(len);
178 if (p->buf == NULL)
179 return(NGR_R_BAD);
180 cp = p->buf;
181 #else
182 if (len > (int)buflen) {
183 errno = ERANGE;
184 return (NGR_R_BAD);
185 }
186 cp = buf;
187 #endif
188
189 if (mp != NULL) {
190 n = strlen(mp) + 1;
191 strcpy(cp, mp);
192 *machinep = cp;
193 cp += n;
194 } else
195 *machinep = NULL;
196
197 if (up != NULL) {
198 n = strlen(up) + 1;
199 strcpy(cp, up);
200 *userp = cp;
201 cp += n;
202 } else
203 *userp = NULL;
204
205 if (dp != NULL) {
206 n = strlen(dp) + 1;
207 strcpy(cp, dp);
208 *domainp = cp;
209 cp += n;
210 } else
211 *domainp = NULL;
212
213 return (NGR_R_OK);
214 }
215 #else /* NGR_R_RETURN */
216 static int getnetgrent_r_unknown_system = 0;
217 #endif /* NGR_R_RETURN */
218 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
219 /*! \file */
220