Thu Jun 9 05:11:17 2011 UTC ()
_gr_copy() can get called with fromgrp->gr_mem == NULL.


(sjg)
diff -r1.62 -r1.63 src/lib/libc/gen/getgrent.c

cvs diff -r1.62 -r1.63 src/lib/libc/gen/getgrent.c (switch to unified diff)

--- src/lib/libc/gen/getgrent.c 2008/04/28 20:22:59 1.62
+++ src/lib/libc/gen/getgrent.c 2011/06/09 05:11:17 1.63
@@ -1,1271 +1,1274 @@ @@ -1,1271 +1,1274 @@
1/* $NetBSD: getgrent.c,v 1.62 2008/04/28 20:22:59 martin Exp $ */ 1/* $NetBSD: getgrent.c,v 1.63 2011/06/09 05:11:17 sjg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999-2000, 2004-2005 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999-2000, 2004-2005 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Luke Mewburn. 8 * by Luke Mewburn.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1989, 1993 33 * Copyright (c) 1989, 1993
34 * The Regents of the University of California. All rights reserved. 34 * The Regents of the University of California. All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors 44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software 45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission. 46 * without specific prior written permission.
47 * 47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 */ 59 */
60 60
61/* 61/*
62 * Portions Copyright (c) 1994, Jason Downs. All Rights Reserved. 62 * Portions Copyright (c) 1994, Jason Downs. All Rights Reserved.
63 * 63 *
64 * Redistribution and use in source and binary forms, with or without 64 * Redistribution and use in source and binary forms, with or without
65 * modification, are permitted provided that the following conditions 65 * modification, are permitted provided that the following conditions
66 * are met: 66 * are met:
67 * 1. Redistributions of source code must retain the above copyright 67 * 1. Redistributions of source code must retain the above copyright
68 * notice, this list of conditions and the following disclaimer. 68 * notice, this list of conditions and the following disclaimer.
69 * 2. Redistributions in binary form must reproduce the above copyright 69 * 2. Redistributions in binary form must reproduce the above copyright
70 * notice, this list of conditions and the following disclaimer in the 70 * notice, this list of conditions and the following disclaimer in the
71 * documentation and/or other materials provided with the distribution. 71 * documentation and/or other materials provided with the distribution.
72 * 72 *
73 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS 73 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
74 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 74 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 75 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, 76 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
77 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 77 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
79 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 79 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
80 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 80 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 81 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 82 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
83 * SUCH DAMAGE. 83 * SUCH DAMAGE.
84 */ 84 */
85 85
86#include <sys/cdefs.h> 86#include <sys/cdefs.h>
87#if defined(LIBC_SCCS) && !defined(lint) 87#if defined(LIBC_SCCS) && !defined(lint)
88#if 0 88#if 0
89static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94"; 89static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94";
90#else 90#else
91__RCSID("$NetBSD: getgrent.c,v 1.62 2008/04/28 20:22:59 martin Exp $"); 91__RCSID("$NetBSD: getgrent.c,v 1.63 2011/06/09 05:11:17 sjg Exp $");
92#endif 92#endif
93#endif /* LIBC_SCCS and not lint */ 93#endif /* LIBC_SCCS and not lint */
94 94
95#include "namespace.h" 95#include "namespace.h"
96#include "reentrant.h" 96#include "reentrant.h"
97 97
98#include <sys/param.h> 98#include <sys/param.h>
99 99
100#include <assert.h> 100#include <assert.h>
101#include <errno.h> 101#include <errno.h>
102#include <grp.h> 102#include <grp.h>
103#include <limits.h> 103#include <limits.h>
104#include <nsswitch.h> 104#include <nsswitch.h>
105#include <stdarg.h> 105#include <stdarg.h>
106#include <stdio.h> 106#include <stdio.h>
107#include <stdlib.h> 107#include <stdlib.h>
108#include <string.h> 108#include <string.h>
109#include <syslog.h> 109#include <syslog.h>
110 110
111#ifdef HESIOD 111#ifdef HESIOD
112#include <hesiod.h> 112#include <hesiod.h>
113#endif 113#endif
114 114
115#ifdef YP 115#ifdef YP
116#include <rpc/rpc.h> 116#include <rpc/rpc.h>
117#include <rpcsvc/yp_prot.h> 117#include <rpcsvc/yp_prot.h>
118#include <rpcsvc/ypclnt.h> 118#include <rpcsvc/ypclnt.h>
119#endif 119#endif
120 120
121#include "gr_private.h" 121#include "gr_private.h"
122 122
123#ifdef __weak_alias 123#ifdef __weak_alias
124__weak_alias(endgrent,_endgrent) 124__weak_alias(endgrent,_endgrent)
125__weak_alias(getgrent,_getgrent) 125__weak_alias(getgrent,_getgrent)
126__weak_alias(getgrent_r,_getgrent_r) 126__weak_alias(getgrent_r,_getgrent_r)
127__weak_alias(getgrgid,_getgrgid) 127__weak_alias(getgrgid,_getgrgid)
128__weak_alias(getgrgid_r,_getgrgid_r) 128__weak_alias(getgrgid_r,_getgrgid_r)
129__weak_alias(getgrnam,_getgrnam) 129__weak_alias(getgrnam,_getgrnam)
130__weak_alias(getgrnam_r,_getgrnam_r) 130__weak_alias(getgrnam_r,_getgrnam_r)
131__weak_alias(setgrent,_setgrent) 131__weak_alias(setgrent,_setgrent)
132__weak_alias(setgroupent,_setgroupent) 132__weak_alias(setgroupent,_setgroupent)
133#endif 133#endif
134 134
135#ifdef _REENTRANT 135#ifdef _REENTRANT
136mutex_t __grmutex = MUTEX_INITIALIZER; 136mutex_t __grmutex = MUTEX_INITIALIZER;
137#endif 137#endif
138 138
139/* 139/*
140 * _gr_memfrombuf 140 * _gr_memfrombuf
141 * Obtain want bytes from buffer (of size buflen) and return a pointer 141 * Obtain want bytes from buffer (of size buflen) and return a pointer
142 * to the available memory after adjusting buffer/buflen. 142 * to the available memory after adjusting buffer/buflen.
143 * Returns NULL if there is insufficient space. 143 * Returns NULL if there is insufficient space.
144 */ 144 */
145static char * 145static char *
146_gr_memfrombuf(size_t want, char **buffer, size_t *buflen) 146_gr_memfrombuf(size_t want, char **buffer, size_t *buflen)
147{ 147{
148 char *rv; 148 char *rv;
149 149
150 if (want > *buflen) { 150 if (want > *buflen) {
151 errno = ERANGE; 151 errno = ERANGE;
152 return NULL; 152 return NULL;
153 } 153 }
154 rv = *buffer; 154 rv = *buffer;
155 *buffer += want; 155 *buffer += want;
156 *buflen -= want; 156 *buflen -= want;
157 return rv; 157 return rv;
158} 158}
159 159
160/* 160/*
161 * _gr_parse 161 * _gr_parse
162 * Parses entry as a line per group(5) (without the trailing \n) 162 * Parses entry as a line per group(5) (without the trailing \n)
163 * and fills in grp with corresponding values; memory for strings 163 * and fills in grp with corresponding values; memory for strings
164 * and arrays will be allocated from buf (of size buflen). 164 * and arrays will be allocated from buf (of size buflen).
165 * Returns 1 if parsed successfully, 0 on parse failure. 165 * Returns 1 if parsed successfully, 0 on parse failure.
166 */ 166 */
167static int 167static int
168_gr_parse(const char *entry, struct group *grp, char *buf, size_t buflen) 168_gr_parse(const char *entry, struct group *grp, char *buf, size_t buflen)
169{ 169{
170 unsigned long id; 170 unsigned long id;
171 const char *bp; 171 const char *bp;
172 char *ep; 172 char *ep;
173 size_t count; 173 size_t count;
174 int memc; 174 int memc;
175 175
176 _DIAGASSERT(entry != NULL); 176 _DIAGASSERT(entry != NULL);
177 _DIAGASSERT(grp != NULL); 177 _DIAGASSERT(grp != NULL);
178 _DIAGASSERT(buf != NULL); 178 _DIAGASSERT(buf != NULL);
179 179
180#define COPYTOBUF(to) \ 180#define COPYTOBUF(to) \
181 do { \ 181 do { \
182 (to) = _gr_memfrombuf(count+1, &buf, &buflen); \ 182 (to) = _gr_memfrombuf(count+1, &buf, &buflen); \
183 if ((to) == NULL) \ 183 if ((to) == NULL) \
184 return 0; \ 184 return 0; \
185 memmove((to), entry, count); \ 185 memmove((to), entry, count); \
186 to[count] = '\0'; \ 186 to[count] = '\0'; \
187 } while (0) /* LINTED */ 187 } while (0) /* LINTED */
188 188
189#if 0 189#if 0
190 if (*entry == '+') /* fail on compat `+' token */ 190 if (*entry == '+') /* fail on compat `+' token */
191 return 0; 191 return 0;
192#endif 192#endif
193 193
194 count = strcspn(entry, ":"); /* parse gr_name */ 194 count = strcspn(entry, ":"); /* parse gr_name */
195 if (entry[count] == '\0') 195 if (entry[count] == '\0')
196 return 0; 196 return 0;
197 COPYTOBUF(grp->gr_name); 197 COPYTOBUF(grp->gr_name);
198 entry += count + 1; 198 entry += count + 1;
199 199
200 count = strcspn(entry, ":"); /* parse gr_passwd */ 200 count = strcspn(entry, ":"); /* parse gr_passwd */
201 if (entry[count] == '\0') 201 if (entry[count] == '\0')
202 return 0; 202 return 0;
203 COPYTOBUF(grp->gr_passwd); 203 COPYTOBUF(grp->gr_passwd);
204 entry += count + 1; 204 entry += count + 1;
205 205
206 count = strcspn(entry, ":"); /* parse gr_gid */ 206 count = strcspn(entry, ":"); /* parse gr_gid */
207 if (entry[count] == '\0') 207 if (entry[count] == '\0')
208 return 0; 208 return 0;
209 id = strtoul(entry, &ep, 10); 209 id = strtoul(entry, &ep, 10);
210 if (id > GID_MAX || *ep != ':') 210 if (id > GID_MAX || *ep != ':')
211 return 0; 211 return 0;
212 grp->gr_gid = (gid_t)id; 212 grp->gr_gid = (gid_t)id;
213 entry += count + 1; 213 entry += count + 1;
214 214
215 memc = 1; /* for final NULL */ 215 memc = 1; /* for final NULL */
216 if (*entry != '\0') 216 if (*entry != '\0')
217 memc++; /* for first item */ 217 memc++; /* for first item */
218 for (bp = entry; *bp != '\0'; bp++) { 218 for (bp = entry; *bp != '\0'; bp++) {
219 if (*bp == ',') 219 if (*bp == ',')
220 memc++; 220 memc++;
221 } 221 }
222 /* grab ALIGNed char **gr_mem from buf */ 222 /* grab ALIGNed char **gr_mem from buf */
223 ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen); 223 ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen);
224 grp->gr_mem = (char **)ALIGN(ep); 224 grp->gr_mem = (char **)ALIGN(ep);
225 if (grp->gr_mem == NULL) 225 if (grp->gr_mem == NULL)
226 return 0; 226 return 0;
227 227
228 for (memc = 0; *entry != '\0'; memc++) { 228 for (memc = 0; *entry != '\0'; memc++) {
229 count = strcspn(entry, ","); /* parse member */ 229 count = strcspn(entry, ","); /* parse member */
230 COPYTOBUF(grp->gr_mem[memc]); 230 COPYTOBUF(grp->gr_mem[memc]);
231 entry += count; 231 entry += count;
232 if (*entry == ',') 232 if (*entry == ',')
233 entry++; 233 entry++;
234 } 234 }
235 235
236#undef COPYTOBUF 236#undef COPYTOBUF
237 237
238 grp->gr_mem[memc] = NULL; 238 grp->gr_mem[memc] = NULL;
239 return 1; 239 return 1;
240} 240}
241 241
242/* 242/*
243 * _gr_copy 243 * _gr_copy
244 * Copy the contents of fromgrp to grp; memory for strings 244 * Copy the contents of fromgrp to grp; memory for strings
245 * and arrays will be allocated from buf (of size buflen). 245 * and arrays will be allocated from buf (of size buflen).
246 * Returns 1 if copied successfully, 0 on copy failure. 246 * Returns 1 if copied successfully, 0 on copy failure.
247 * NOTE: fromgrp must not use buf for its own pointers. 247 * NOTE: fromgrp must not use buf for its own pointers.
248 */ 248 */
249static int 249static int
250_gr_copy(struct group *fromgrp, struct group *grp, char *buf, size_t buflen) 250_gr_copy(struct group *fromgrp, struct group *grp, char *buf, size_t buflen)
251{ 251{
252 char *ep; 252 char *ep;
253 int memc; 253 int memc;
254 254
255 _DIAGASSERT(fromgrp != NULL); 255 _DIAGASSERT(fromgrp != NULL);
256 _DIAGASSERT(grp != NULL); 256 _DIAGASSERT(grp != NULL);
257 _DIAGASSERT(buf != NULL); 257 _DIAGASSERT(buf != NULL);
258 258
259#define COPYSTR(to, from) \ 259#define COPYSTR(to, from) \
260 do { \ 260 do { \
261 size_t count = strlen((from)); \ 261 size_t count = strlen((from)); \
262 (to) = _gr_memfrombuf(count+1, &buf, &buflen); \ 262 (to) = _gr_memfrombuf(count+1, &buf, &buflen); \
263 if ((to) == NULL) \ 263 if ((to) == NULL) \
264 return 0; \ 264 return 0; \
265 memmove((to), (from), count); \ 265 memmove((to), (from), count); \
266 to[count] = '\0'; \ 266 to[count] = '\0'; \
267 } while (0) /* LINTED */ 267 } while (0) /* LINTED */
268 268
269 COPYSTR(grp->gr_name, fromgrp->gr_name); 269 COPYSTR(grp->gr_name, fromgrp->gr_name);
270 COPYSTR(grp->gr_passwd, fromgrp->gr_passwd); 270 COPYSTR(grp->gr_passwd, fromgrp->gr_passwd);
271 grp->gr_gid = fromgrp->gr_gid; 271 grp->gr_gid = fromgrp->gr_gid;
272 272
 273 if (fromgrp->gr_mem == NULL)
 274 return 0;
 275
273 for (memc = 0; fromgrp->gr_mem[memc]; memc++) 276 for (memc = 0; fromgrp->gr_mem[memc]; memc++)
274 continue; 277 continue;
275 memc++; /* for final NULL */ 278 memc++; /* for final NULL */
276 279
277 /* grab ALIGNed char **gr_mem from buf */ 280 /* grab ALIGNed char **gr_mem from buf */
278 ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen); 281 ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen);
279 grp->gr_mem = (char **)ALIGN(ep); 282 grp->gr_mem = (char **)ALIGN(ep);
280 if (grp->gr_mem == NULL) 283 if (grp->gr_mem == NULL)
281 return 0; 284 return 0;
282 285
283 for (memc = 0; fromgrp->gr_mem[memc]; memc++) { 286 for (memc = 0; fromgrp->gr_mem[memc]; memc++) {
284 COPYSTR(grp->gr_mem[memc], fromgrp->gr_mem[memc]); 287 COPYSTR(grp->gr_mem[memc], fromgrp->gr_mem[memc]);
285 } 288 }
286 289
287#undef COPYSTR 290#undef COPYSTR
288 291
289 grp->gr_mem[memc] = NULL; 292 grp->gr_mem[memc] = NULL;
290 return 1; 293 return 1;
291} 294}
292 295
293 /* 296 /*
294 * files methods 297 * files methods
295 */ 298 */
296 299
297int 300int
298__grstart_files(struct __grstate_files *state) 301__grstart_files(struct __grstate_files *state)
299{ 302{
300 303
301 _DIAGASSERT(state != NULL); 304 _DIAGASSERT(state != NULL);
302 305
303 if (state->fp == NULL) { 306 if (state->fp == NULL) {
304 state->fp = fopen(_PATH_GROUP, "r"); 307 state->fp = fopen(_PATH_GROUP, "r");
305 if (state->fp == NULL) 308 if (state->fp == NULL)
306 return NS_UNAVAIL; 309 return NS_UNAVAIL;
307 } else { 310 } else {
308 rewind(state->fp); 311 rewind(state->fp);
309 } 312 }
310 return NS_SUCCESS; 313 return NS_SUCCESS;
311} 314}
312 315
313int 316int
314__grend_files(struct __grstate_files *state) 317__grend_files(struct __grstate_files *state)
315{ 318{
316 319
317 _DIAGASSERT(state != NULL); 320 _DIAGASSERT(state != NULL);
318 321
319 if (state->fp) { 322 if (state->fp) {
320 (void) fclose(state->fp); 323 (void) fclose(state->fp);
321 state->fp = NULL; 324 state->fp = NULL;
322 } 325 }
323 return NS_SUCCESS; 326 return NS_SUCCESS;
324} 327}
325 328
326/* 329/*
327 * __grscan_files 330 * __grscan_files
328 * Scan state->fp for the next desired entry. 331 * Scan state->fp for the next desired entry.
329 * If search is zero, return the next entry. 332 * If search is zero, return the next entry.
330 * If search is non-zero, look for a specific name (if name != NULL), 333 * If search is non-zero, look for a specific name (if name != NULL),
331 * or a specific gid (if name == NULL). 334 * or a specific gid (if name == NULL).
332 * Sets *retval to the errno if the result is not NS_SUCCESS 335 * Sets *retval to the errno if the result is not NS_SUCCESS
333 * or NS_NOTFOUND. 336 * or NS_NOTFOUND.
334 */ 337 */
335int 338int
336__grscan_files(int *retval, struct group *grp, char *buffer, size_t buflen, 339__grscan_files(int *retval, struct group *grp, char *buffer, size_t buflen,
337 struct __grstate_files *state, int search, const char *name, gid_t gid) 340 struct __grstate_files *state, int search, const char *name, gid_t gid)
338{ 341{
339 int rv; 342 int rv;
340 char filebuf[_GETGR_R_SIZE_MAX], *ep; 343 char filebuf[_GETGR_R_SIZE_MAX], *ep;
341 344
342 _DIAGASSERT(retval != NULL); 345 _DIAGASSERT(retval != NULL);
343 _DIAGASSERT(grp != NULL); 346 _DIAGASSERT(grp != NULL);
344 _DIAGASSERT(buffer != NULL); 347 _DIAGASSERT(buffer != NULL);
345 _DIAGASSERT(state != NULL); 348 _DIAGASSERT(state != NULL);
346 /* name is NULL to indicate searching for gid */ 349 /* name is NULL to indicate searching for gid */
347 350
348 *retval = 0; 351 *retval = 0;
349 352
350 if (state->fp == NULL) { /* only start if file not open yet */ 353 if (state->fp == NULL) { /* only start if file not open yet */
351 rv = __grstart_files(state); 354 rv = __grstart_files(state);
352 if (rv != NS_SUCCESS) 355 if (rv != NS_SUCCESS)
353 goto filesgrscan_out; 356 goto filesgrscan_out;
354 } 357 }
355 358
356 rv = NS_NOTFOUND; 359 rv = NS_NOTFOUND;
357 360
358 /* scan line by line */ 361 /* scan line by line */
359 while (fgets(filebuf, sizeof(filebuf), state->fp) != NULL) { 362 while (fgets(filebuf, sizeof(filebuf), state->fp) != NULL) {
360 ep = strchr(filebuf, '\n'); 363 ep = strchr(filebuf, '\n');
361 if (ep == NULL) { /* skip lines that are too big */ 364 if (ep == NULL) { /* skip lines that are too big */
362 int ch; 365 int ch;
363 366
364 while ((ch = getc(state->fp)) != '\n' && ch != EOF) 367 while ((ch = getc(state->fp)) != '\n' && ch != EOF)
365 continue; 368 continue;
366 continue; 369 continue;
367 } 370 }
368 *ep = '\0'; /* clear trailing \n */ 371 *ep = '\0'; /* clear trailing \n */
369 372
370 if (filebuf[0] == '+') /* skip compat line */ 373 if (filebuf[0] == '+') /* skip compat line */
371 continue; 374 continue;
372 375
373 /* validate line */ 376 /* validate line */
374 if (! _gr_parse(filebuf, grp, buffer, buflen)) { 377 if (! _gr_parse(filebuf, grp, buffer, buflen)) {
375 continue; /* skip bad lines */ 378 continue; /* skip bad lines */
376 } 379 }
377 if (! search) { /* just want this one */ 380 if (! search) { /* just want this one */
378 rv = NS_SUCCESS; 381 rv = NS_SUCCESS;
379 break; 382 break;
380 } 383 }
381 /* want specific */ 384 /* want specific */
382 if ((name && strcmp(name, grp->gr_name) == 0) || 385 if ((name && strcmp(name, grp->gr_name) == 0) ||
383 (!name && gid == grp->gr_gid)) { 386 (!name && gid == grp->gr_gid)) {
384 rv = NS_SUCCESS; 387 rv = NS_SUCCESS;
385 break; 388 break;
386 } 389 }
387 } 390 }
388 391
389 filesgrscan_out: 392 filesgrscan_out:
390 if (rv != NS_SUCCESS && rv != NS_NOTFOUND) 393 if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
391 *retval = errno; 394 *retval = errno;
392 return rv; 395 return rv;
393} 396}
394 397
395 398
396static struct __grstate_files _files_state; 399static struct __grstate_files _files_state;
397 /* storage for non _r functions */ 400 /* storage for non _r functions */
398static struct group _files_group; 401static struct group _files_group;
399static char _files_groupbuf[_GETGR_R_SIZE_MAX]; 402static char _files_groupbuf[_GETGR_R_SIZE_MAX];
400 403
401/*ARGSUSED*/ 404/*ARGSUSED*/
402static int 405static int
403_files_setgrent(void *nsrv, void *nscb, va_list ap) 406_files_setgrent(void *nsrv, void *nscb, va_list ap)
404{ 407{
405 408
406 _files_state.stayopen = 0; 409 _files_state.stayopen = 0;
407 return __grstart_files(&_files_state); 410 return __grstart_files(&_files_state);
408} 411}
409 412
410/*ARGSUSED*/ 413/*ARGSUSED*/
411static int 414static int
412_files_setgroupent(void *nsrv, void *nscb, va_list ap) 415_files_setgroupent(void *nsrv, void *nscb, va_list ap)
413{ 416{
414 int *retval = va_arg(ap, int *); 417 int *retval = va_arg(ap, int *);
415 int stayopen = va_arg(ap, int); 418 int stayopen = va_arg(ap, int);
416 419
417 int rv; 420 int rv;
418 421
419 _files_state.stayopen = stayopen; 422 _files_state.stayopen = stayopen;
420 rv = __grstart_files(&_files_state); 423 rv = __grstart_files(&_files_state);
421 *retval = (rv == NS_SUCCESS); 424 *retval = (rv == NS_SUCCESS);
422 return rv; 425 return rv;
423} 426}
424 427
425/*ARGSUSED*/ 428/*ARGSUSED*/
426static int 429static int
427_files_endgrent(void *nsrv, void *nscb, va_list ap) 430_files_endgrent(void *nsrv, void *nscb, va_list ap)
428{ 431{
429 432
430 _files_state.stayopen = 0; 433 _files_state.stayopen = 0;
431 return __grend_files(&_files_state); 434 return __grend_files(&_files_state);
432} 435}
433 436
434/*ARGSUSED*/ 437/*ARGSUSED*/
435static int 438static int
436_files_getgrent(void *nsrv, void *nscb, va_list ap) 439_files_getgrent(void *nsrv, void *nscb, va_list ap)
437{ 440{
438 struct group **retval = va_arg(ap, struct group **); 441 struct group **retval = va_arg(ap, struct group **);
439 442
440 int rv, rerror; 443 int rv, rerror;
441 444
442 _DIAGASSERT(retval != NULL); 445 _DIAGASSERT(retval != NULL);
443 446
444 *retval = NULL; 447 *retval = NULL;
445 rv = __grscan_files(&rerror, &_files_group, 448 rv = __grscan_files(&rerror, &_files_group,
446 _files_groupbuf, sizeof(_files_groupbuf), 449 _files_groupbuf, sizeof(_files_groupbuf),
447 &_files_state, 0, NULL, 0); 450 &_files_state, 0, NULL, 0);
448 if (rv == NS_SUCCESS) 451 if (rv == NS_SUCCESS)
449 *retval = &_files_group; 452 *retval = &_files_group;
450 return rv; 453 return rv;
451} 454}
452 455
453/*ARGSUSED*/ 456/*ARGSUSED*/
454static int 457static int
455_files_getgrent_r(void *nsrv, void *nscb, va_list ap) 458_files_getgrent_r(void *nsrv, void *nscb, va_list ap)
456{ 459{
457 int *retval = va_arg(ap, int *); 460 int *retval = va_arg(ap, int *);
458 struct group *grp = va_arg(ap, struct group *); 461 struct group *grp = va_arg(ap, struct group *);
459 char *buffer = va_arg(ap, char *); 462 char *buffer = va_arg(ap, char *);
460 size_t buflen = va_arg(ap, size_t); 463 size_t buflen = va_arg(ap, size_t);
461 struct group **result = va_arg(ap, struct group **); 464 struct group **result = va_arg(ap, struct group **);
462 465
463 int rv; 466 int rv;
464 467
465 _DIAGASSERT(retval != NULL); 468 _DIAGASSERT(retval != NULL);
466 _DIAGASSERT(grp != NULL); 469 _DIAGASSERT(grp != NULL);
467 _DIAGASSERT(buffer != NULL); 470 _DIAGASSERT(buffer != NULL);
468 _DIAGASSERT(result != NULL); 471 _DIAGASSERT(result != NULL);
469 472
470 rv = __grscan_files(retval, grp, buffer, buflen, 473 rv = __grscan_files(retval, grp, buffer, buflen,
471 &_files_state, 0, NULL, 0); 474 &_files_state, 0, NULL, 0);
472 if (rv == NS_SUCCESS) 475 if (rv == NS_SUCCESS)
473 *result = grp; 476 *result = grp;
474 else 477 else
475 *result = NULL; 478 *result = NULL;
476 return rv; 479 return rv;
477} 480}
478 481
479/*ARGSUSED*/ 482/*ARGSUSED*/
480static int 483static int
481_files_getgrgid(void *nsrv, void *nscb, va_list ap) 484_files_getgrgid(void *nsrv, void *nscb, va_list ap)
482{ 485{
483 struct group **retval = va_arg(ap, struct group **); 486 struct group **retval = va_arg(ap, struct group **);
484 gid_t gid = va_arg(ap, gid_t); 487 gid_t gid = va_arg(ap, gid_t);
485 488
486 int rv, rerror; 489 int rv, rerror;
487 490
488 _DIAGASSERT(retval != NULL); 491 _DIAGASSERT(retval != NULL);
489 492
490 *retval = NULL; 493 *retval = NULL;
491 rv = __grstart_files(&_files_state); 494 rv = __grstart_files(&_files_state);
492 if (rv != NS_SUCCESS) 495 if (rv != NS_SUCCESS)
493 return rv; 496 return rv;
494 rv = __grscan_files(&rerror, &_files_group, 497 rv = __grscan_files(&rerror, &_files_group,
495 _files_groupbuf, sizeof(_files_groupbuf), 498 _files_groupbuf, sizeof(_files_groupbuf),
496 &_files_state, 1, NULL, gid); 499 &_files_state, 1, NULL, gid);
497 if (!_files_state.stayopen) 500 if (!_files_state.stayopen)
498 __grend_files(&_files_state); 501 __grend_files(&_files_state);
499 if (rv == NS_SUCCESS) 502 if (rv == NS_SUCCESS)
500 *retval = &_files_group; 503 *retval = &_files_group;
501 return rv; 504 return rv;
502} 505}
503 506
504/*ARGSUSED*/ 507/*ARGSUSED*/
505static int 508static int
506_files_getgrgid_r(void *nsrv, void *nscb, va_list ap) 509_files_getgrgid_r(void *nsrv, void *nscb, va_list ap)
507{ 510{
508 int *retval = va_arg(ap, int *); 511 int *retval = va_arg(ap, int *);
509 gid_t gid = va_arg(ap, gid_t); 512 gid_t gid = va_arg(ap, gid_t);
510 struct group *grp = va_arg(ap, struct group *); 513 struct group *grp = va_arg(ap, struct group *);
511 char *buffer = va_arg(ap, char *); 514 char *buffer = va_arg(ap, char *);
512 size_t buflen = va_arg(ap, size_t); 515 size_t buflen = va_arg(ap, size_t);
513 struct group **result = va_arg(ap, struct group **); 516 struct group **result = va_arg(ap, struct group **);
514 517
515 struct __grstate_files state; 518 struct __grstate_files state;
516 int rv; 519 int rv;
517 520
518 _DIAGASSERT(retval != NULL); 521 _DIAGASSERT(retval != NULL);
519 _DIAGASSERT(grp != NULL); 522 _DIAGASSERT(grp != NULL);
520 _DIAGASSERT(buffer != NULL); 523 _DIAGASSERT(buffer != NULL);
521 _DIAGASSERT(result != NULL); 524 _DIAGASSERT(result != NULL);
522 525
523 *result = NULL; 526 *result = NULL;
524 memset(&state, 0, sizeof(state)); 527 memset(&state, 0, sizeof(state));
525 rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, NULL, gid); 528 rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, NULL, gid);
526 __grend_files(&state); 529 __grend_files(&state);
527 if (rv == NS_SUCCESS) 530 if (rv == NS_SUCCESS)
528 *result = grp; 531 *result = grp;
529 return rv; 532 return rv;
530} 533}
531 534
532/*ARGSUSED*/ 535/*ARGSUSED*/
533static int 536static int
534_files_getgrnam(void *nsrv, void *nscb, va_list ap) 537_files_getgrnam(void *nsrv, void *nscb, va_list ap)
535{ 538{
536 struct group **retval = va_arg(ap, struct group **); 539 struct group **retval = va_arg(ap, struct group **);
537 const char *name = va_arg(ap, const char *); 540 const char *name = va_arg(ap, const char *);
538 541
539 int rv, rerror; 542 int rv, rerror;
540 543
541 _DIAGASSERT(retval != NULL); 544 _DIAGASSERT(retval != NULL);
542 545
543 *retval = NULL; 546 *retval = NULL;
544 rv = __grstart_files(&_files_state); 547 rv = __grstart_files(&_files_state);
545 if (rv != NS_SUCCESS) 548 if (rv != NS_SUCCESS)
546 return rv; 549 return rv;
547 rv = __grscan_files(&rerror, &_files_group, 550 rv = __grscan_files(&rerror, &_files_group,
548 _files_groupbuf, sizeof(_files_groupbuf), 551 _files_groupbuf, sizeof(_files_groupbuf),
549 &_files_state, 1, name, 0); 552 &_files_state, 1, name, 0);
550 if (!_files_state.stayopen) 553 if (!_files_state.stayopen)
551 __grend_files(&_files_state); 554 __grend_files(&_files_state);
552 if (rv == NS_SUCCESS) 555 if (rv == NS_SUCCESS)
553 *retval = &_files_group; 556 *retval = &_files_group;
554 return rv; 557 return rv;
555} 558}
556 559
557/*ARGSUSED*/ 560/*ARGSUSED*/
558static int 561static int
559_files_getgrnam_r(void *nsrv, void *nscb, va_list ap) 562_files_getgrnam_r(void *nsrv, void *nscb, va_list ap)
560{ 563{
561 int *retval = va_arg(ap, int *); 564 int *retval = va_arg(ap, int *);
562 const char *name = va_arg(ap, const char *); 565 const char *name = va_arg(ap, const char *);
563 struct group *grp = va_arg(ap, struct group *); 566 struct group *grp = va_arg(ap, struct group *);
564 char *buffer = va_arg(ap, char *); 567 char *buffer = va_arg(ap, char *);
565 size_t buflen = va_arg(ap, size_t); 568 size_t buflen = va_arg(ap, size_t);
566 struct group **result = va_arg(ap, struct group **); 569 struct group **result = va_arg(ap, struct group **);
567 570
568 struct __grstate_files state; 571 struct __grstate_files state;
569 int rv; 572 int rv;
570 573
571 _DIAGASSERT(retval != NULL); 574 _DIAGASSERT(retval != NULL);
572 _DIAGASSERT(grp != NULL); 575 _DIAGASSERT(grp != NULL);
573 _DIAGASSERT(buffer != NULL); 576 _DIAGASSERT(buffer != NULL);
574 _DIAGASSERT(result != NULL); 577 _DIAGASSERT(result != NULL);
575 578
576 *result = NULL; 579 *result = NULL;
577 memset(&state, 0, sizeof(state)); 580 memset(&state, 0, sizeof(state));
578 rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, name, 0); 581 rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, name, 0);
579 __grend_files(&state); 582 __grend_files(&state);
580 if (rv == NS_SUCCESS) 583 if (rv == NS_SUCCESS)
581 *result = grp; 584 *result = grp;
582 return rv; 585 return rv;
583} 586}
584 587
585 588
586#ifdef HESIOD 589#ifdef HESIOD
587 /* 590 /*
588 * dns methods 591 * dns methods
589 */ 592 */
590 593
591int 594int
592__grstart_dns(struct __grstate_dns *state) 595__grstart_dns(struct __grstate_dns *state)
593{ 596{
594 597
595 _DIAGASSERT(state != NULL); 598 _DIAGASSERT(state != NULL);
596 599
597 state->num = 0; 600 state->num = 0;
598 if (state->context == NULL) { /* setup Hesiod */ 601 if (state->context == NULL) { /* setup Hesiod */
599 if (hesiod_init(&state->context) == -1) 602 if (hesiod_init(&state->context) == -1)
600 return NS_UNAVAIL; 603 return NS_UNAVAIL;
601 } 604 }
602 605
603 return NS_SUCCESS; 606 return NS_SUCCESS;
604} 607}
605 608
606int 609int
607__grend_dns(struct __grstate_dns *state) 610__grend_dns(struct __grstate_dns *state)
608{ 611{
609 612
610 _DIAGASSERT(state != NULL); 613 _DIAGASSERT(state != NULL);
611 614
612 state->num = 0; 615 state->num = 0;
613 if (state->context) { 616 if (state->context) {
614 hesiod_end(state->context); 617 hesiod_end(state->context);
615 state->context = NULL; 618 state->context = NULL;
616 } 619 }
617 return NS_SUCCESS; 620 return NS_SUCCESS;
618} 621}
619 622
620/* 623/*
621 * __grscan_dns 624 * __grscan_dns
622 * Search Hesiod for the next desired entry. 625 * Search Hesiod for the next desired entry.
623 * If search is zero, return the next entry. 626 * If search is zero, return the next entry.
624 * If search is non-zero, look for a specific name (if name != NULL), 627 * If search is non-zero, look for a specific name (if name != NULL),
625 * or a specific gid (if name == NULL). 628 * or a specific gid (if name == NULL).
626 */ 629 */
627int 630int
628__grscan_dns(int *retval, struct group *grp, char *buffer, size_t buflen, 631__grscan_dns(int *retval, struct group *grp, char *buffer, size_t buflen,
629 struct __grstate_dns *state, int search, const char *name, gid_t gid) 632 struct __grstate_dns *state, int search, const char *name, gid_t gid)
630{ 633{
631 const char **curzone; 634 const char **curzone;
632 char **hp, *ep; 635 char **hp, *ep;
633 int rv; 636 int rv;
634 637
635 static const char *zones_gid_group[] = { 638 static const char *zones_gid_group[] = {
636 "gid", 639 "gid",
637 "group", 640 "group",
638 NULL 641 NULL
639 }; 642 };
640 643
641 static const char *zones_group[] = { 644 static const char *zones_group[] = {
642 "group", 645 "group",
643 NULL 646 NULL
644 }; 647 };
645 648
646 _DIAGASSERT(retval != NULL); 649 _DIAGASSERT(retval != NULL);
647 _DIAGASSERT(grp != NULL); 650 _DIAGASSERT(grp != NULL);
648 _DIAGASSERT(buffer != NULL); 651 _DIAGASSERT(buffer != NULL);
649 _DIAGASSERT(state != NULL); 652 _DIAGASSERT(state != NULL);
650 /* name is NULL to indicate searching for gid */ 653 /* name is NULL to indicate searching for gid */
651 654
652 *retval = 0; 655 *retval = 0;
653 656
654 if (state->context == NULL) { /* only start if Hesiod not setup */ 657 if (state->context == NULL) { /* only start if Hesiod not setup */
655 rv = __grstart_dns(state); 658 rv = __grstart_dns(state);
656 if (rv != NS_SUCCESS) 659 if (rv != NS_SUCCESS)
657 return rv; 660 return rv;
658 } 661 }
659 662
660 next_dns_entry: 663 next_dns_entry:
661 hp = NULL; 664 hp = NULL;
662 rv = NS_NOTFOUND; 665 rv = NS_NOTFOUND;
663 666
664 if (! search) { /* find next entry */ 667 if (! search) { /* find next entry */
665 if (state->num == -1) /* exhausted search */ 668 if (state->num == -1) /* exhausted search */
666 return NS_NOTFOUND; 669 return NS_NOTFOUND;
667 /* find group-NNN */ 670 /* find group-NNN */
668 snprintf(buffer, buflen, "group-%u", state->num); 671 snprintf(buffer, buflen, "group-%u", state->num);
669 state->num++; 672 state->num++;
670 curzone = zones_group; 673 curzone = zones_group;
671 } else if (name) { /* find group name */ 674 } else if (name) { /* find group name */
672 snprintf(buffer, buflen, "%s", name); 675 snprintf(buffer, buflen, "%s", name);
673 curzone = zones_group; 676 curzone = zones_group;
674 } else { /* find gid */ 677 } else { /* find gid */
675 snprintf(buffer, buflen, "%u", (unsigned int)gid); 678 snprintf(buffer, buflen, "%u", (unsigned int)gid);
676 curzone = zones_gid_group; 679 curzone = zones_gid_group;
677 } 680 }
678 681
679 for (; *curzone; curzone++) { /* search zones */ 682 for (; *curzone; curzone++) { /* search zones */
680 hp = hesiod_resolve(state->context, buffer, *curzone); 683 hp = hesiod_resolve(state->context, buffer, *curzone);
681 if (hp != NULL) 684 if (hp != NULL)
682 break; 685 break;
683 if (errno != ENOENT) { 686 if (errno != ENOENT) {
684 rv = NS_UNAVAIL; 687 rv = NS_UNAVAIL;
685 goto dnsgrscan_out; 688 goto dnsgrscan_out;
686 } 689 }
687 } 690 }
688 if (*curzone == NULL) { 691 if (*curzone == NULL) {
689 if (! search) 692 if (! search)
690 state->num = -1; 693 state->num = -1;
691 goto dnsgrscan_out; 694 goto dnsgrscan_out;
692 } 695 }
693 696
694 if ((ep = strchr(hp[0], '\n')) != NULL) 697 if ((ep = strchr(hp[0], '\n')) != NULL)
695 *ep = '\0'; /* clear trailing \n */ 698 *ep = '\0'; /* clear trailing \n */
696 if (_gr_parse(hp[0], grp, buffer, buflen)) { /* validate line */ 699 if (_gr_parse(hp[0], grp, buffer, buflen)) { /* validate line */
697 if (! search) { /* just want this one */ 700 if (! search) { /* just want this one */
698 rv = NS_SUCCESS; 701 rv = NS_SUCCESS;
699 } else if ((name && strcmp(name, grp->gr_name) == 0) || 702 } else if ((name && strcmp(name, grp->gr_name) == 0) ||
700 (!name && gid == grp->gr_gid)) { /* want specific */ 703 (!name && gid == grp->gr_gid)) { /* want specific */
701 rv = NS_SUCCESS; 704 rv = NS_SUCCESS;
702 } 705 }
703 } else { /* dodgy entry */ 706 } else { /* dodgy entry */
704 if (!search) { /* try again if ! searching */ 707 if (!search) { /* try again if ! searching */
705 hesiod_free_list(state->context, hp); 708 hesiod_free_list(state->context, hp);
706 goto next_dns_entry; 709 goto next_dns_entry;
707 } 710 }
708 } 711 }
709 712
710 dnsgrscan_out: 713 dnsgrscan_out:
711 if (rv != NS_SUCCESS && rv != NS_NOTFOUND) 714 if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
712 *retval = errno; 715 *retval = errno;
713 if (hp) 716 if (hp)
714 hesiod_free_list(state->context, hp); 717 hesiod_free_list(state->context, hp);
715 return rv; 718 return rv;
716} 719}
717 720
718static struct __grstate_dns _dns_state; 721static struct __grstate_dns _dns_state;
719 /* storage for non _r functions */ 722 /* storage for non _r functions */
720static struct group _dns_group; 723static struct group _dns_group;
721static char _dns_groupbuf[_GETGR_R_SIZE_MAX]; 724static char _dns_groupbuf[_GETGR_R_SIZE_MAX];
722 725
723/*ARGSUSED*/ 726/*ARGSUSED*/
724static int 727static int
725_dns_setgrent(void *nsrv, void *nscb, va_list ap) 728_dns_setgrent(void *nsrv, void *nscb, va_list ap)
726{ 729{
727 730
728 _dns_state.stayopen = 0; 731 _dns_state.stayopen = 0;
729 return __grstart_dns(&_dns_state); 732 return __grstart_dns(&_dns_state);
730} 733}
731 734
732/*ARGSUSED*/ 735/*ARGSUSED*/
733static int 736static int
734_dns_setgroupent(void *nsrv, void *nscb, va_list ap) 737_dns_setgroupent(void *nsrv, void *nscb, va_list ap)
735{ 738{
736 int *retval = va_arg(ap, int *); 739 int *retval = va_arg(ap, int *);
737 int stayopen = va_arg(ap, int); 740 int stayopen = va_arg(ap, int);
738 741
739 int rv; 742 int rv;
740 743
741 _dns_state.stayopen = stayopen; 744 _dns_state.stayopen = stayopen;
742 rv = __grstart_dns(&_dns_state); 745 rv = __grstart_dns(&_dns_state);
743 *retval = (rv == NS_SUCCESS); 746 *retval = (rv == NS_SUCCESS);
744 return rv; 747 return rv;
745} 748}
746 749
747/*ARGSUSED*/ 750/*ARGSUSED*/
748static int 751static int
749_dns_endgrent(void *nsrv, void *nscb, va_list ap) 752_dns_endgrent(void *nsrv, void *nscb, va_list ap)
750{ 753{
751 754
752 _dns_state.stayopen = 0; 755 _dns_state.stayopen = 0;
753 return __grend_dns(&_dns_state); 756 return __grend_dns(&_dns_state);
754} 757}
755 758
756/*ARGSUSED*/ 759/*ARGSUSED*/
757static int 760static int
758_dns_getgrent(void *nsrv, void *nscb, va_list ap) 761_dns_getgrent(void *nsrv, void *nscb, va_list ap)
759{ 762{
760 struct group **retval = va_arg(ap, struct group **); 763 struct group **retval = va_arg(ap, struct group **);
761 764
762 int rv, rerror; 765 int rv, rerror;
763 766
764 _DIAGASSERT(retval != NULL); 767 _DIAGASSERT(retval != NULL);
765 768
766 *retval = NULL; 769 *retval = NULL;
767 rv = __grscan_dns(&rerror, &_dns_group, 770 rv = __grscan_dns(&rerror, &_dns_group,
768 _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 0, NULL, 0); 771 _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 0, NULL, 0);
769 if (rv == NS_SUCCESS) 772 if (rv == NS_SUCCESS)
770 *retval = &_dns_group; 773 *retval = &_dns_group;
771 return rv; 774 return rv;
772} 775}
773 776
774/*ARGSUSED*/ 777/*ARGSUSED*/
775static int 778static int
776_dns_getgrent_r(void *nsrv, void *nscb, va_list ap) 779_dns_getgrent_r(void *nsrv, void *nscb, va_list ap)
777{ 780{
778 int *retval = va_arg(ap, int *); 781 int *retval = va_arg(ap, int *);
779 struct group *grp = va_arg(ap, struct group *); 782 struct group *grp = va_arg(ap, struct group *);
780 char *buffer = va_arg(ap, char *); 783 char *buffer = va_arg(ap, char *);
781 size_t buflen = va_arg(ap, size_t); 784 size_t buflen = va_arg(ap, size_t);
782 struct group **result = va_arg(ap, struct group **); 785 struct group **result = va_arg(ap, struct group **);
783 786
784 int rv; 787 int rv;
785 788
786 _DIAGASSERT(retval != NULL); 789 _DIAGASSERT(retval != NULL);
787 _DIAGASSERT(grp != NULL); 790 _DIAGASSERT(grp != NULL);
788 _DIAGASSERT(buffer != NULL); 791 _DIAGASSERT(buffer != NULL);
789 _DIAGASSERT(result != NULL); 792 _DIAGASSERT(result != NULL);
790 793
791 rv = __grscan_dns(retval, grp, buffer, buflen, 794 rv = __grscan_dns(retval, grp, buffer, buflen,
792 &_dns_state, 0, NULL, 0); 795 &_dns_state, 0, NULL, 0);
793 if (rv == NS_SUCCESS) 796 if (rv == NS_SUCCESS)
794 *result = grp; 797 *result = grp;
795 else 798 else
796 *result = NULL; 799 *result = NULL;
797 return rv; 800 return rv;
798} 801}
799/*ARGSUSED*/ 802/*ARGSUSED*/
800static int 803static int
801_dns_getgrgid(void *nsrv, void *nscb, va_list ap) 804_dns_getgrgid(void *nsrv, void *nscb, va_list ap)
802{ 805{
803 struct group **retval = va_arg(ap, struct group **); 806 struct group **retval = va_arg(ap, struct group **);
804 gid_t gid = va_arg(ap, gid_t); 807 gid_t gid = va_arg(ap, gid_t);
805 808
806 int rv, rerror; 809 int rv, rerror;
807 810
808 _DIAGASSERT(retval != NULL); 811 _DIAGASSERT(retval != NULL);
809 812
810 *retval = NULL; 813 *retval = NULL;
811 rv = __grstart_dns(&_dns_state); 814 rv = __grstart_dns(&_dns_state);
812 if (rv != NS_SUCCESS) 815 if (rv != NS_SUCCESS)
813 return rv; 816 return rv;
814 rv = __grscan_dns(&rerror, &_dns_group, 817 rv = __grscan_dns(&rerror, &_dns_group,
815 _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, NULL, gid); 818 _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, NULL, gid);
816 if (!_dns_state.stayopen) 819 if (!_dns_state.stayopen)
817 __grend_dns(&_dns_state); 820 __grend_dns(&_dns_state);
818 if (rv == NS_SUCCESS) 821 if (rv == NS_SUCCESS)
819 *retval = &_dns_group; 822 *retval = &_dns_group;
820 return rv; 823 return rv;
821} 824}
822 825
823/*ARGSUSED*/ 826/*ARGSUSED*/
824static int 827static int
825_dns_getgrgid_r(void *nsrv, void *nscb, va_list ap) 828_dns_getgrgid_r(void *nsrv, void *nscb, va_list ap)
826{ 829{
827 int *retval = va_arg(ap, int *); 830 int *retval = va_arg(ap, int *);
828 gid_t gid = va_arg(ap, gid_t); 831 gid_t gid = va_arg(ap, gid_t);
829 struct group *grp = va_arg(ap, struct group *); 832 struct group *grp = va_arg(ap, struct group *);
830 char *buffer = va_arg(ap, char *); 833 char *buffer = va_arg(ap, char *);
831 size_t buflen = va_arg(ap, size_t); 834 size_t buflen = va_arg(ap, size_t);
832 struct group **result = va_arg(ap, struct group **); 835 struct group **result = va_arg(ap, struct group **);
833 836
834 struct __grstate_dns state; 837 struct __grstate_dns state;
835 int rv; 838 int rv;
836 839
837 _DIAGASSERT(retval != NULL); 840 _DIAGASSERT(retval != NULL);
838 _DIAGASSERT(grp != NULL); 841 _DIAGASSERT(grp != NULL);
839 _DIAGASSERT(buffer != NULL); 842 _DIAGASSERT(buffer != NULL);
840 _DIAGASSERT(result != NULL); 843 _DIAGASSERT(result != NULL);
841 844
842 *result = NULL; 845 *result = NULL;
843 memset(&state, 0, sizeof(state)); 846 memset(&state, 0, sizeof(state));
844 rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, NULL, gid); 847 rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, NULL, gid);
845 __grend_dns(&state); 848 __grend_dns(&state);
846 if (rv == NS_SUCCESS) 849 if (rv == NS_SUCCESS)
847 *result = grp; 850 *result = grp;
848 return rv; 851 return rv;
849} 852}
850 853
851/*ARGSUSED*/ 854/*ARGSUSED*/
852static int 855static int
853_dns_getgrnam(void *nsrv, void *nscb, va_list ap) 856_dns_getgrnam(void *nsrv, void *nscb, va_list ap)
854{ 857{
855 struct group **retval = va_arg(ap, struct group **); 858 struct group **retval = va_arg(ap, struct group **);
856 const char *name = va_arg(ap, const char *); 859 const char *name = va_arg(ap, const char *);
857 860
858 int rv, rerror; 861 int rv, rerror;
859 862
860 _DIAGASSERT(retval != NULL); 863 _DIAGASSERT(retval != NULL);
861 864
862 *retval = NULL; 865 *retval = NULL;
863 rv = __grstart_dns(&_dns_state); 866 rv = __grstart_dns(&_dns_state);
864 if (rv != NS_SUCCESS) 867 if (rv != NS_SUCCESS)
865 return rv; 868 return rv;
866 rv = __grscan_dns(&rerror, &_dns_group, 869 rv = __grscan_dns(&rerror, &_dns_group,
867 _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, name, 0); 870 _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, name, 0);
868 if (!_dns_state.stayopen) 871 if (!_dns_state.stayopen)
869 __grend_dns(&_dns_state); 872 __grend_dns(&_dns_state);
870 if (rv == NS_SUCCESS) 873 if (rv == NS_SUCCESS)
871 *retval = &_dns_group; 874 *retval = &_dns_group;
872 return rv; 875 return rv;
873} 876}
874 877
875/*ARGSUSED*/ 878/*ARGSUSED*/
876static int 879static int
877_dns_getgrnam_r(void *nsrv, void *nscb, va_list ap) 880_dns_getgrnam_r(void *nsrv, void *nscb, va_list ap)
878{ 881{
879 int *retval = va_arg(ap, int *); 882 int *retval = va_arg(ap, int *);
880 const char *name = va_arg(ap, const char *); 883 const char *name = va_arg(ap, const char *);
881 struct group *grp = va_arg(ap, struct group *); 884 struct group *grp = va_arg(ap, struct group *);
882 char *buffer = va_arg(ap, char *); 885 char *buffer = va_arg(ap, char *);
883 size_t buflen = va_arg(ap, size_t); 886 size_t buflen = va_arg(ap, size_t);
884 struct group **result = va_arg(ap, struct group **); 887 struct group **result = va_arg(ap, struct group **);
885 888
886 struct __grstate_dns state; 889 struct __grstate_dns state;
887 int rv; 890 int rv;
888 891
889 _DIAGASSERT(retval != NULL); 892 _DIAGASSERT(retval != NULL);
890 _DIAGASSERT(grp != NULL); 893 _DIAGASSERT(grp != NULL);
891 _DIAGASSERT(buffer != NULL); 894 _DIAGASSERT(buffer != NULL);
892 _DIAGASSERT(result != NULL); 895 _DIAGASSERT(result != NULL);
893 896
894 *result = NULL; 897 *result = NULL;
895 memset(&state, 0, sizeof(state)); 898 memset(&state, 0, sizeof(state));
896 rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, name, 0); 899 rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, name, 0);
897 __grend_dns(&state); 900 __grend_dns(&state);
898 if (rv == NS_SUCCESS) 901 if (rv == NS_SUCCESS)
899 *result = grp; 902 *result = grp;
900 return rv; 903 return rv;
901} 904}
902 905
903#endif /* HESIOD */ 906#endif /* HESIOD */
904 907
905 908
906#ifdef YP 909#ifdef YP
907 /* 910 /*
908 * nis methods 911 * nis methods
909 */ 912 */
910 913
911int 914int
912__grstart_nis(struct __grstate_nis *state) 915__grstart_nis(struct __grstate_nis *state)
913{ 916{
914 917
915 _DIAGASSERT(state != NULL); 918 _DIAGASSERT(state != NULL);
916 919
917 state->done = 0; 920 state->done = 0;
918 if (state->current) { 921 if (state->current) {
919 free(state->current); 922 free(state->current);
920 state->current = NULL; 923 state->current = NULL;
921 } 924 }
922 if (state->domain == NULL) { /* setup NIS */ 925 if (state->domain == NULL) { /* setup NIS */
923 switch (yp_get_default_domain(&state->domain)) { 926 switch (yp_get_default_domain(&state->domain)) {
924 case 0: 927 case 0:
925 break; 928 break;
926 case YPERR_RESRC: 929 case YPERR_RESRC:
927 return NS_TRYAGAIN; 930 return NS_TRYAGAIN;
928 default: 931 default:
929 return NS_UNAVAIL; 932 return NS_UNAVAIL;
930 } 933 }
931 } 934 }
932 return NS_SUCCESS; 935 return NS_SUCCESS;
933} 936}
934 937
935int 938int
936__grend_nis(struct __grstate_nis *state) 939__grend_nis(struct __grstate_nis *state)
937{ 940{
938 941
939 _DIAGASSERT(state != NULL); 942 _DIAGASSERT(state != NULL);
940 943
941 if (state->domain) { 944 if (state->domain) {
942 state->domain = NULL; 945 state->domain = NULL;
943 } 946 }
944 state->done = 0; 947 state->done = 0;
945 if (state->current) { 948 if (state->current) {
946 free(state->current); 949 free(state->current);
947 state->current = NULL; 950 state->current = NULL;
948 } 951 }
949 return NS_SUCCESS; 952 return NS_SUCCESS;
950} 953}
951 954
952/* 955/*
953 * __grscan_nis 956 * __grscan_nis
954 * Search NIS for the next desired entry. 957 * Search NIS for the next desired entry.
955 * If search is zero, return the next entry. 958 * If search is zero, return the next entry.
956 * If search is non-zero, look for a specific name (if name != NULL), 959 * If search is non-zero, look for a specific name (if name != NULL),
957 * or a specific gid (if name == NULL). 960 * or a specific gid (if name == NULL).
958 */ 961 */
959int 962int
960__grscan_nis(int *retval, struct group *grp, char *buffer, size_t buflen, 963__grscan_nis(int *retval, struct group *grp, char *buffer, size_t buflen,
961 struct __grstate_nis *state, int search, const char *name, gid_t gid) 964 struct __grstate_nis *state, int search, const char *name, gid_t gid)
962{ 965{
963 const char *map; 966 const char *map;
964 char *key, *data; 967 char *key, *data;
965 int nisr, rv, keylen, datalen; 968 int nisr, rv, keylen, datalen;
966 969
967 _DIAGASSERT(retval != NULL); 970 _DIAGASSERT(retval != NULL);
968 _DIAGASSERT(grp != NULL); 971 _DIAGASSERT(grp != NULL);
969 _DIAGASSERT(buffer != NULL); 972 _DIAGASSERT(buffer != NULL);
970 _DIAGASSERT(state != NULL); 973 _DIAGASSERT(state != NULL);
971 /* name is NULL to indicate searching for gid */ 974 /* name is NULL to indicate searching for gid */
972 975
973 *retval = 0; 976 *retval = 0;
974 977
975 if (state->domain == NULL) { /* only start if NIS not setup */ 978 if (state->domain == NULL) { /* only start if NIS not setup */
976 rv = __grstart_nis(state); 979 rv = __grstart_nis(state);
977 if (rv != NS_SUCCESS) 980 if (rv != NS_SUCCESS)
978 return rv; 981 return rv;
979 } 982 }
980 983
981 next_nis_entry: 984 next_nis_entry:
982 key = NULL; 985 key = NULL;
983 data = NULL; 986 data = NULL;
984 rv = NS_SUCCESS; 987 rv = NS_SUCCESS;
985 988
986 if (! search) { /* find next entry */ 989 if (! search) { /* find next entry */
987 if (state->done) /* exhausted search */ 990 if (state->done) /* exhausted search */
988 return NS_NOTFOUND; 991 return NS_NOTFOUND;
989 map = "group.byname"; 992 map = "group.byname";
990 if (state->current) { /* already searching */ 993 if (state->current) { /* already searching */
991 nisr = yp_next(state->domain, map, 994 nisr = yp_next(state->domain, map,
992 state->current, state->currentlen, 995 state->current, state->currentlen,
993 &key, &keylen, &data, &datalen); 996 &key, &keylen, &data, &datalen);
994 free(state->current); 997 free(state->current);
995 state->current = NULL; 998 state->current = NULL;
996 switch (nisr) { 999 switch (nisr) {
997 case 0: 1000 case 0:
998 state->current = key; 1001 state->current = key;
999 state->currentlen = keylen; 1002 state->currentlen = keylen;
1000 key = NULL; 1003 key = NULL;
1001 break; 1004 break;
1002 case YPERR_NOMORE: 1005 case YPERR_NOMORE:
1003 rv = NS_NOTFOUND; 1006 rv = NS_NOTFOUND;
1004 state->done = 1; 1007 state->done = 1;
1005 break; 1008 break;
1006 default: 1009 default:
1007 rv = NS_UNAVAIL; 1010 rv = NS_UNAVAIL;
1008 break; 1011 break;
1009 } 1012 }
1010 } else { /* new search */ 1013 } else { /* new search */
1011 if (yp_first(state->domain, map, 1014 if (yp_first(state->domain, map,
1012 &state->current, &state->currentlen, 1015 &state->current, &state->currentlen,
1013 &data, &datalen)) { 1016 &data, &datalen)) {
1014 rv = NS_UNAVAIL; 1017 rv = NS_UNAVAIL;
1015 } 1018 }
1016 } 1019 }
1017 } else { /* search for specific item */ 1020 } else { /* search for specific item */
1018 if (name) { /* find group name */ 1021 if (name) { /* find group name */
1019 snprintf(buffer, buflen, "%s", name); 1022 snprintf(buffer, buflen, "%s", name);
1020 map = "group.byname"; 1023 map = "group.byname";
1021 } else { /* find gid */ 1024 } else { /* find gid */
1022 snprintf(buffer, buflen, "%u", (unsigned int)gid); 1025 snprintf(buffer, buflen, "%u", (unsigned int)gid);
1023 map = "group.bygid"; 1026 map = "group.bygid";
1024 } 1027 }
1025 nisr = yp_match(state->domain, map, buffer, (int)strlen(buffer), 1028 nisr = yp_match(state->domain, map, buffer, (int)strlen(buffer),
1026 &data, &datalen); 1029 &data, &datalen);
1027 switch (nisr) { 1030 switch (nisr) {
1028 case 0: 1031 case 0:
1029 break; 1032 break;
1030 case YPERR_KEY: 1033 case YPERR_KEY:
1031 rv = NS_NOTFOUND; 1034 rv = NS_NOTFOUND;
1032 break; 1035 break;
1033 default: 1036 default:
1034 rv = NS_UNAVAIL; 1037 rv = NS_UNAVAIL;
1035 break; 1038 break;
1036 } 1039 }
1037 } 1040 }
1038 if (rv == NS_SUCCESS) { /* validate data */ 1041 if (rv == NS_SUCCESS) { /* validate data */
1039 data[datalen] = '\0'; /* clear trailing \n */ 1042 data[datalen] = '\0'; /* clear trailing \n */
1040 if (_gr_parse(data, grp, buffer, buflen)) { 1043 if (_gr_parse(data, grp, buffer, buflen)) {
1041 if (! search) { /* just want this one */ 1044 if (! search) { /* just want this one */
1042 rv = NS_SUCCESS; 1045 rv = NS_SUCCESS;
1043 } else if ((name && strcmp(name, grp->gr_name) == 0) || 1046 } else if ((name && strcmp(name, grp->gr_name) == 0) ||
1044 (!name && gid == grp->gr_gid)) { 1047 (!name && gid == grp->gr_gid)) {
1045 /* want specific */ 1048 /* want specific */
1046 rv = NS_SUCCESS; 1049 rv = NS_SUCCESS;
1047 } 1050 }
1048 } else { /* dodgy entry */ 1051 } else { /* dodgy entry */
1049 if (!search) { /* try again if ! searching */ 1052 if (!search) { /* try again if ! searching */
1050 free(data); 1053 free(data);
1051 goto next_nis_entry; 1054 goto next_nis_entry;
1052 } 1055 }
1053 } 1056 }
1054 } 1057 }
1055 1058
1056 if (rv != NS_SUCCESS && rv != NS_NOTFOUND) 1059 if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
1057 *retval = errno; 1060 *retval = errno;
1058 if (key) 1061 if (key)
1059 free(key); 1062 free(key);
1060 if (data) 1063 if (data)
1061 free(data); 1064 free(data);
1062 return rv; 1065 return rv;
1063} 1066}
1064 1067
1065static struct __grstate_nis _nis_state; 1068static struct __grstate_nis _nis_state;
1066 /* storage for non _r functions */ 1069 /* storage for non _r functions */
1067static struct group _nis_group; 1070static struct group _nis_group;
1068static char _nis_groupbuf[_GETGR_R_SIZE_MAX]; 1071static char _nis_groupbuf[_GETGR_R_SIZE_MAX];
1069 1072
1070/*ARGSUSED*/ 1073/*ARGSUSED*/
1071static int 1074static int
1072_nis_setgrent(void *nsrv, void *nscb, va_list ap) 1075_nis_setgrent(void *nsrv, void *nscb, va_list ap)
1073{ 1076{
1074 1077
1075 _nis_state.stayopen = 0; 1078 _nis_state.stayopen = 0;
1076 return __grstart_nis(&_nis_state); 1079 return __grstart_nis(&_nis_state);
1077} 1080}
1078 1081
1079/*ARGSUSED*/ 1082/*ARGSUSED*/
1080static int 1083static int
1081_nis_setgroupent(void *nsrv, void *nscb, va_list ap) 1084_nis_setgroupent(void *nsrv, void *nscb, va_list ap)
1082{ 1085{
1083 int *retval = va_arg(ap, int *); 1086 int *retval = va_arg(ap, int *);
1084 int stayopen = va_arg(ap, int); 1087 int stayopen = va_arg(ap, int);
1085 1088
1086 int rv; 1089 int rv;
1087 1090
1088 _nis_state.stayopen = stayopen; 1091 _nis_state.stayopen = stayopen;
1089 rv = __grstart_nis(&_nis_state); 1092 rv = __grstart_nis(&_nis_state);
1090 *retval = (rv == NS_SUCCESS); 1093 *retval = (rv == NS_SUCCESS);
1091 return rv; 1094 return rv;
1092} 1095}
1093 1096
1094/*ARGSUSED*/ 1097/*ARGSUSED*/
1095static int 1098static int
1096_nis_endgrent(void *nsrv, void *nscb, va_list ap) 1099_nis_endgrent(void *nsrv, void *nscb, va_list ap)
1097{ 1100{
1098 1101
1099 return __grend_nis(&_nis_state); 1102 return __grend_nis(&_nis_state);
1100} 1103}
1101 1104
1102/*ARGSUSED*/ 1105/*ARGSUSED*/
1103static int 1106static int
1104_nis_getgrent(void *nsrv, void *nscb, va_list ap) 1107_nis_getgrent(void *nsrv, void *nscb, va_list ap)
1105{ 1108{
1106 struct group **retval = va_arg(ap, struct group **); 1109 struct group **retval = va_arg(ap, struct group **);
1107 1110
1108 int rv, rerror; 1111 int rv, rerror;
1109 1112
1110 _DIAGASSERT(retval != NULL); 1113 _DIAGASSERT(retval != NULL);
1111 1114
1112 *retval = NULL; 1115 *retval = NULL;
1113 rv = __grscan_nis(&rerror, &_nis_group, 1116 rv = __grscan_nis(&rerror, &_nis_group,
1114 _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 0, NULL, 0); 1117 _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 0, NULL, 0);
1115 if (rv == NS_SUCCESS) 1118 if (rv == NS_SUCCESS)
1116 *retval = &_nis_group; 1119 *retval = &_nis_group;
1117 return rv; 1120 return rv;
1118} 1121}
1119 1122
1120/*ARGSUSED*/ 1123/*ARGSUSED*/
1121static int 1124static int
1122_nis_getgrent_r(void *nsrv, void *nscb, va_list ap) 1125_nis_getgrent_r(void *nsrv, void *nscb, va_list ap)
1123{ 1126{
1124 int *retval = va_arg(ap, int *); 1127 int *retval = va_arg(ap, int *);
1125 struct group *grp = va_arg(ap, struct group *); 1128 struct group *grp = va_arg(ap, struct group *);
1126 char *buffer = va_arg(ap, char *); 1129 char *buffer = va_arg(ap, char *);
1127 size_t buflen = va_arg(ap, size_t); 1130 size_t buflen = va_arg(ap, size_t);
1128 struct group **result = va_arg(ap, struct group **); 1131 struct group **result = va_arg(ap, struct group **);
1129 1132
1130 int rv; 1133 int rv;
1131 1134
1132 _DIAGASSERT(retval != NULL); 1135 _DIAGASSERT(retval != NULL);
1133 _DIAGASSERT(grp != NULL); 1136 _DIAGASSERT(grp != NULL);
1134 _DIAGASSERT(buffer != NULL); 1137 _DIAGASSERT(buffer != NULL);
1135 _DIAGASSERT(result != NULL); 1138 _DIAGASSERT(result != NULL);
1136 1139
1137 rv = __grscan_nis(retval, grp, buffer, buflen, 1140 rv = __grscan_nis(retval, grp, buffer, buflen,
1138 &_nis_state, 0, NULL, 0); 1141 &_nis_state, 0, NULL, 0);
1139 if (rv == NS_SUCCESS) 1142 if (rv == NS_SUCCESS)
1140 *result = grp; 1143 *result = grp;
1141 else 1144 else
1142 *result = NULL; 1145 *result = NULL;
1143 return rv; 1146 return rv;
1144} 1147}
1145 1148
1146/*ARGSUSED*/ 1149/*ARGSUSED*/
1147static int 1150static int
1148_nis_getgrgid(void *nsrv, void *nscb, va_list ap) 1151_nis_getgrgid(void *nsrv, void *nscb, va_list ap)
1149{ 1152{
1150 struct group **retval = va_arg(ap, struct group **); 1153 struct group **retval = va_arg(ap, struct group **);
1151 gid_t gid = va_arg(ap, gid_t); 1154 gid_t gid = va_arg(ap, gid_t);
1152 1155
1153 int rv, rerror; 1156 int rv, rerror;
1154 1157
1155 _DIAGASSERT(retval != NULL); 1158 _DIAGASSERT(retval != NULL);
1156 1159
1157 *retval = NULL; 1160 *retval = NULL;
1158 rv = __grstart_nis(&_nis_state); 1161 rv = __grstart_nis(&_nis_state);
1159 if (rv != NS_SUCCESS) 1162 if (rv != NS_SUCCESS)
1160 return rv; 1163 return rv;
1161 rv = __grscan_nis(&rerror, &_nis_group, 1164 rv = __grscan_nis(&rerror, &_nis_group,
1162 _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, NULL, gid); 1165 _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, NULL, gid);
1163 if (!_nis_state.stayopen) 1166 if (!_nis_state.stayopen)
1164 __grend_nis(&_nis_state); 1167 __grend_nis(&_nis_state);
1165 if (rv == NS_SUCCESS) 1168 if (rv == NS_SUCCESS)
1166 *retval = &_nis_group; 1169 *retval = &_nis_group;
1167 return rv; 1170 return rv;
1168} 1171}
1169 1172
1170/*ARGSUSED*/ 1173/*ARGSUSED*/
1171static int 1174static int
1172_nis_getgrgid_r(void *nsrv, void *nscb, va_list ap) 1175_nis_getgrgid_r(void *nsrv, void *nscb, va_list ap)
1173{ 1176{
1174 int *retval = va_arg(ap, int *); 1177 int *retval = va_arg(ap, int *);
1175 gid_t gid = va_arg(ap, gid_t); 1178 gid_t gid = va_arg(ap, gid_t);
1176 struct group *grp = va_arg(ap, struct group *); 1179 struct group *grp = va_arg(ap, struct group *);
1177 char *buffer = va_arg(ap, char *); 1180 char *buffer = va_arg(ap, char *);
1178 size_t buflen = va_arg(ap, size_t); 1181 size_t buflen = va_arg(ap, size_t);
1179 struct group **result = va_arg(ap, struct group **); 1182 struct group **result = va_arg(ap, struct group **);
1180 1183
1181 struct __grstate_nis state; 1184 struct __grstate_nis state;
1182 int rv; 1185 int rv;
1183 1186
1184 _DIAGASSERT(retval != NULL); 1187 _DIAGASSERT(retval != NULL);
1185 _DIAGASSERT(grp != NULL); 1188 _DIAGASSERT(grp != NULL);
1186 _DIAGASSERT(buffer != NULL); 1189 _DIAGASSERT(buffer != NULL);
1187 _DIAGASSERT(result != NULL); 1190 _DIAGASSERT(result != NULL);
1188 1191
1189 *result = NULL; 1192 *result = NULL;
1190 memset(&state, 0, sizeof(state)); 1193 memset(&state, 0, sizeof(state));
1191 rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, NULL, gid); 1194 rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, NULL, gid);
1192 __grend_nis(&state); 1195 __grend_nis(&state);
1193 if (rv == NS_SUCCESS) 1196 if (rv == NS_SUCCESS)
1194 *result = grp; 1197 *result = grp;
1195 return rv; 1198 return rv;
1196} 1199}
1197 1200
1198/*ARGSUSED*/ 1201/*ARGSUSED*/
1199static int 1202static int
1200_nis_getgrnam(void *nsrv, void *nscb, va_list ap) 1203_nis_getgrnam(void *nsrv, void *nscb, va_list ap)
1201{ 1204{
1202 struct group **retval = va_arg(ap, struct group **); 1205 struct group **retval = va_arg(ap, struct group **);
1203 const char *name = va_arg(ap, const char *); 1206 const char *name = va_arg(ap, const char *);
1204 1207
1205 int rv, rerror; 1208 int rv, rerror;
1206 1209
1207 _DIAGASSERT(retval != NULL); 1210 _DIAGASSERT(retval != NULL);
1208 1211
1209 *retval = NULL; 1212 *retval = NULL;
1210 rv = __grstart_nis(&_nis_state); 1213 rv = __grstart_nis(&_nis_state);
1211 if (rv != NS_SUCCESS) 1214 if (rv != NS_SUCCESS)
1212 return rv; 1215 return rv;
1213 rv = __grscan_nis(&rerror, &_nis_group, 1216 rv = __grscan_nis(&rerror, &_nis_group,
1214 _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, name, 0); 1217 _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, name, 0);
1215 if (!_nis_state.stayopen) 1218 if (!_nis_state.stayopen)
1216 __grend_nis(&_nis_state); 1219 __grend_nis(&_nis_state);
1217 if (rv == NS_SUCCESS) 1220 if (rv == NS_SUCCESS)
1218 *retval = &_nis_group; 1221 *retval = &_nis_group;
1219 return rv; 1222 return rv;
1220} 1223}
1221 1224
1222/*ARGSUSED*/ 1225/*ARGSUSED*/
1223static int 1226static int
1224_nis_getgrnam_r(void *nsrv, void *nscb, va_list ap) 1227_nis_getgrnam_r(void *nsrv, void *nscb, va_list ap)
1225{ 1228{
1226 int *retval = va_arg(ap, int *); 1229 int *retval = va_arg(ap, int *);
1227 const char *name = va_arg(ap, const char *); 1230 const char *name = va_arg(ap, const char *);
1228 struct group *grp = va_arg(ap, struct group *); 1231 struct group *grp = va_arg(ap, struct group *);
1229 char *buffer = va_arg(ap, char *); 1232 char *buffer = va_arg(ap, char *);
1230 size_t buflen = va_arg(ap, size_t); 1233 size_t buflen = va_arg(ap, size_t);
1231 struct group **result = va_arg(ap, struct group **); 1234 struct group **result = va_arg(ap, struct group **);
1232 1235
1233 struct __grstate_nis state; 1236 struct __grstate_nis state;
1234 int rv; 1237 int rv;
1235 1238
1236 _DIAGASSERT(retval != NULL); 1239 _DIAGASSERT(retval != NULL);
1237 _DIAGASSERT(grp != NULL); 1240 _DIAGASSERT(grp != NULL);
1238 _DIAGASSERT(buffer != NULL); 1241 _DIAGASSERT(buffer != NULL);
1239 _DIAGASSERT(result != NULL); 1242 _DIAGASSERT(result != NULL);
1240 1243
1241 *result = NULL; 1244 *result = NULL;
1242 memset(&state, 0, sizeof(state)); 1245 memset(&state, 0, sizeof(state));
1243 rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, name, 0); 1246 rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, name, 0);
1244 __grend_nis(&state); 1247 __grend_nis(&state);
1245 if (rv == NS_SUCCESS) 1248 if (rv == NS_SUCCESS)
1246 *result = grp; 1249 *result = grp;
1247 return rv; 1250 return rv;
1248} 1251}
1249 1252
1250#endif /* YP */ 1253#endif /* YP */
1251 1254
1252 1255
1253#ifdef _GROUP_COMPAT 1256#ifdef _GROUP_COMPAT
1254 /* 1257 /*
1255 * compat methods 1258 * compat methods
1256 */ 1259 */
1257 1260
1258int 1261int
1259__grstart_compat(struct __grstate_compat *state) 1262__grstart_compat(struct __grstate_compat *state)
1260{ 1263{
1261 1264
1262 _DIAGASSERT(state != NULL); 1265 _DIAGASSERT(state != NULL);
1263 1266
1264 if (state->fp == NULL) { 1267 if (state->fp == NULL) {
1265 state->fp = fopen(_PATH_GROUP, "r"); 1268 state->fp = fopen(_PATH_GROUP, "r");
1266 if (state->fp == NULL) 1269 if (state->fp == NULL)
1267 return NS_UNAVAIL; 1270 return NS_UNAVAIL;
1268 } else { 1271 } else {
1269 rewind(state->fp); 1272 rewind(state->fp);
1270 } 1273 }
1271 return NS_SUCCESS; 1274 return NS_SUCCESS;