xref: /freebsd-src/contrib/mtree/getid.c (revision c6ec7d31830ab1c80edae95ad5e4b9dba10c47ac)
1*c6ec7d31SBrooks Davis /*	$NetBSD: getid.c,v 1.7 2008/04/28 20:24:17 martin Exp $	*/
2*c6ec7d31SBrooks Davis /*	from: NetBSD: getpwent.c,v 1.48 2000/10/03 03:22:26 enami Exp */
3*c6ec7d31SBrooks Davis /*	from: NetBSD: getgrent.c,v 1.41 2002/01/12 23:51:30 lukem Exp */
4*c6ec7d31SBrooks Davis 
5*c6ec7d31SBrooks Davis /*
6*c6ec7d31SBrooks Davis  * Copyright (c) 1987, 1988, 1989, 1993, 1994, 1995
7*c6ec7d31SBrooks Davis  *	The Regents of the University of California.  All rights reserved.
8*c6ec7d31SBrooks Davis  *
9*c6ec7d31SBrooks Davis  * Redistribution and use in source and binary forms, with or without
10*c6ec7d31SBrooks Davis  * modification, are permitted provided that the following conditions
11*c6ec7d31SBrooks Davis  * are met:
12*c6ec7d31SBrooks Davis  * 1. Redistributions of source code must retain the above copyright
13*c6ec7d31SBrooks Davis  *    notice, this list of conditions and the following disclaimer.
14*c6ec7d31SBrooks Davis  * 2. Redistributions in binary form must reproduce the above copyright
15*c6ec7d31SBrooks Davis  *    notice, this list of conditions and the following disclaimer in the
16*c6ec7d31SBrooks Davis  *    documentation and/or other materials provided with the distribution.
17*c6ec7d31SBrooks Davis  * 3. Neither the name of the University nor the names of its contributors
18*c6ec7d31SBrooks Davis  *    may be used to endorse or promote products derived from this software
19*c6ec7d31SBrooks Davis  *    without specific prior written permission.
20*c6ec7d31SBrooks Davis  *
21*c6ec7d31SBrooks Davis  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*c6ec7d31SBrooks Davis  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*c6ec7d31SBrooks Davis  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*c6ec7d31SBrooks Davis  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*c6ec7d31SBrooks Davis  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*c6ec7d31SBrooks Davis  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*c6ec7d31SBrooks Davis  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*c6ec7d31SBrooks Davis  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*c6ec7d31SBrooks Davis  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*c6ec7d31SBrooks Davis  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*c6ec7d31SBrooks Davis  * SUCH DAMAGE.
32*c6ec7d31SBrooks Davis  */
33*c6ec7d31SBrooks Davis 
34*c6ec7d31SBrooks Davis /*-
35*c6ec7d31SBrooks Davis  * Copyright (c) 2002 The NetBSD Foundation, Inc.
36*c6ec7d31SBrooks Davis  * All rights reserved.
37*c6ec7d31SBrooks Davis  *
38*c6ec7d31SBrooks Davis  * This code is derived from software contributed to The NetBSD Foundation
39*c6ec7d31SBrooks Davis  * by Luke Mewburn of Wasabi Systems.
40*c6ec7d31SBrooks Davis  *
41*c6ec7d31SBrooks Davis  * Redistribution and use in source and binary forms, with or without
42*c6ec7d31SBrooks Davis  * modification, are permitted provided that the following conditions
43*c6ec7d31SBrooks Davis  * are met:
44*c6ec7d31SBrooks Davis  * 1. Redistributions of source code must retain the above copyright
45*c6ec7d31SBrooks Davis  *    notice, this list of conditions and the following disclaimer.
46*c6ec7d31SBrooks Davis  * 2. Redistributions in binary form must reproduce the above copyright
47*c6ec7d31SBrooks Davis  *    notice, this list of conditions and the following disclaimer in the
48*c6ec7d31SBrooks Davis  *    documentation and/or other materials provided with the distribution.
49*c6ec7d31SBrooks Davis  *
50*c6ec7d31SBrooks Davis  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
51*c6ec7d31SBrooks Davis  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
52*c6ec7d31SBrooks Davis  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53*c6ec7d31SBrooks Davis  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
54*c6ec7d31SBrooks Davis  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55*c6ec7d31SBrooks Davis  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56*c6ec7d31SBrooks Davis  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57*c6ec7d31SBrooks Davis  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58*c6ec7d31SBrooks Davis  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59*c6ec7d31SBrooks Davis  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60*c6ec7d31SBrooks Davis  * POSSIBILITY OF SUCH DAMAGE.
61*c6ec7d31SBrooks Davis  */
62*c6ec7d31SBrooks Davis 
63*c6ec7d31SBrooks Davis #if HAVE_NBTOOL_CONFIG_H
64*c6ec7d31SBrooks Davis #include "nbtool_config.h"
65*c6ec7d31SBrooks Davis #endif
66*c6ec7d31SBrooks Davis 
67*c6ec7d31SBrooks Davis #include <sys/cdefs.h>
68*c6ec7d31SBrooks Davis __RCSID("$NetBSD: getid.c,v 1.7 2008/04/28 20:24:17 martin Exp $");
69*c6ec7d31SBrooks Davis 
70*c6ec7d31SBrooks Davis #include <sys/param.h>
71*c6ec7d31SBrooks Davis 
72*c6ec7d31SBrooks Davis #include <grp.h>
73*c6ec7d31SBrooks Davis #include <limits.h>
74*c6ec7d31SBrooks Davis #include <pwd.h>
75*c6ec7d31SBrooks Davis #include <stdlib.h>
76*c6ec7d31SBrooks Davis #include <stdio.h>
77*c6ec7d31SBrooks Davis #include <string.h>
78*c6ec7d31SBrooks Davis #include <time.h>
79*c6ec7d31SBrooks Davis #include <unistd.h>
80*c6ec7d31SBrooks Davis 
81*c6ec7d31SBrooks Davis #include "extern.h"
82*c6ec7d31SBrooks Davis 
83*c6ec7d31SBrooks Davis static	struct group *	gi_getgrnam(const char *);
84*c6ec7d31SBrooks Davis static	struct group *	gi_getgrgid(gid_t);
85*c6ec7d31SBrooks Davis static	int		gi_setgroupent(int);
86*c6ec7d31SBrooks Davis static	void		gi_endgrent(void);
87*c6ec7d31SBrooks Davis static	int		grstart(void);
88*c6ec7d31SBrooks Davis static	int		grscan(int, gid_t, const char *);
89*c6ec7d31SBrooks Davis static	int		grmatchline(int, gid_t, const char *);
90*c6ec7d31SBrooks Davis 
91*c6ec7d31SBrooks Davis static	struct passwd *	gi_getpwnam(const char *);
92*c6ec7d31SBrooks Davis static	struct passwd *	gi_getpwuid(uid_t);
93*c6ec7d31SBrooks Davis static	int		gi_setpassent(int);
94*c6ec7d31SBrooks Davis static	void		gi_endpwent(void);
95*c6ec7d31SBrooks Davis static	int		pwstart(void);
96*c6ec7d31SBrooks Davis static	int		pwscan(int, uid_t, const char *);
97*c6ec7d31SBrooks Davis static	int		pwmatchline(int, uid_t, const char *);
98*c6ec7d31SBrooks Davis 
99*c6ec7d31SBrooks Davis #define	MAXGRP		200
100*c6ec7d31SBrooks Davis #define	MAXLINELENGTH	1024
101*c6ec7d31SBrooks Davis 
102*c6ec7d31SBrooks Davis static	FILE		*_gr_fp;
103*c6ec7d31SBrooks Davis static	struct group	_gr_group;
104*c6ec7d31SBrooks Davis static	int		_gr_stayopen;
105*c6ec7d31SBrooks Davis static	int		_gr_filesdone;
106*c6ec7d31SBrooks Davis static	FILE		*_pw_fp;
107*c6ec7d31SBrooks Davis static	struct passwd	_pw_passwd;	/* password structure */
108*c6ec7d31SBrooks Davis static	int		_pw_stayopen;	/* keep fd's open */
109*c6ec7d31SBrooks Davis static	int		_pw_filesdone;
110*c6ec7d31SBrooks Davis 
111*c6ec7d31SBrooks Davis static	char		grfile[MAXPATHLEN];
112*c6ec7d31SBrooks Davis static	char		pwfile[MAXPATHLEN];
113*c6ec7d31SBrooks Davis 
114*c6ec7d31SBrooks Davis static	char		*members[MAXGRP];
115*c6ec7d31SBrooks Davis static	char		grline[MAXLINELENGTH];
116*c6ec7d31SBrooks Davis static	char		pwline[MAXLINELENGTH];
117*c6ec7d31SBrooks Davis 
118*c6ec7d31SBrooks Davis int
119*c6ec7d31SBrooks Davis setup_getid(const char *dir)
120*c6ec7d31SBrooks Davis {
121*c6ec7d31SBrooks Davis 	if (dir == NULL)
122*c6ec7d31SBrooks Davis 		return (0);
123*c6ec7d31SBrooks Davis 
124*c6ec7d31SBrooks Davis 				/* close existing databases */
125*c6ec7d31SBrooks Davis 	gi_endgrent();
126*c6ec7d31SBrooks Davis 	gi_endpwent();
127*c6ec7d31SBrooks Davis 
128*c6ec7d31SBrooks Davis 				/* build paths to new databases */
129*c6ec7d31SBrooks Davis 	snprintf(grfile, sizeof(grfile), "%s/group", dir);
130*c6ec7d31SBrooks Davis 	snprintf(pwfile, sizeof(pwfile), "%s/master.passwd", dir);
131*c6ec7d31SBrooks Davis 
132*c6ec7d31SBrooks Davis 				/* try to open new databases */
133*c6ec7d31SBrooks Davis 	if (!grstart() || !pwstart())
134*c6ec7d31SBrooks Davis 		return (0);
135*c6ec7d31SBrooks Davis 
136*c6ec7d31SBrooks Davis 				/* switch pwcache(3) lookup functions */
137*c6ec7d31SBrooks Davis 	if (pwcache_groupdb(gi_setgroupent, gi_endgrent,
138*c6ec7d31SBrooks Davis 			    gi_getgrnam, gi_getgrgid) == -1
139*c6ec7d31SBrooks Davis 	    || pwcache_userdb(gi_setpassent, gi_endpwent,
140*c6ec7d31SBrooks Davis 			    gi_getpwnam, gi_getpwuid) == -1)
141*c6ec7d31SBrooks Davis 		return (0);
142*c6ec7d31SBrooks Davis 
143*c6ec7d31SBrooks Davis 	return (1);
144*c6ec7d31SBrooks Davis }
145*c6ec7d31SBrooks Davis 
146*c6ec7d31SBrooks Davis 
147*c6ec7d31SBrooks Davis /*
148*c6ec7d31SBrooks Davis  * group lookup functions
149*c6ec7d31SBrooks Davis  */
150*c6ec7d31SBrooks Davis 
151*c6ec7d31SBrooks Davis static struct group *
152*c6ec7d31SBrooks Davis gi_getgrnam(const char *name)
153*c6ec7d31SBrooks Davis {
154*c6ec7d31SBrooks Davis 	int rval;
155*c6ec7d31SBrooks Davis 
156*c6ec7d31SBrooks Davis 	if (!grstart())
157*c6ec7d31SBrooks Davis 		return NULL;
158*c6ec7d31SBrooks Davis 	rval = grscan(1, 0, name);
159*c6ec7d31SBrooks Davis 	if (!_gr_stayopen)
160*c6ec7d31SBrooks Davis 		endgrent();
161*c6ec7d31SBrooks Davis 	return (rval) ? &_gr_group : NULL;
162*c6ec7d31SBrooks Davis }
163*c6ec7d31SBrooks Davis 
164*c6ec7d31SBrooks Davis static struct group *
165*c6ec7d31SBrooks Davis gi_getgrgid(gid_t gid)
166*c6ec7d31SBrooks Davis {
167*c6ec7d31SBrooks Davis 	int rval;
168*c6ec7d31SBrooks Davis 
169*c6ec7d31SBrooks Davis 	if (!grstart())
170*c6ec7d31SBrooks Davis 		return NULL;
171*c6ec7d31SBrooks Davis 	rval = grscan(1, gid, NULL);
172*c6ec7d31SBrooks Davis 	if (!_gr_stayopen)
173*c6ec7d31SBrooks Davis 		endgrent();
174*c6ec7d31SBrooks Davis 	return (rval) ? &_gr_group : NULL;
175*c6ec7d31SBrooks Davis }
176*c6ec7d31SBrooks Davis 
177*c6ec7d31SBrooks Davis static int
178*c6ec7d31SBrooks Davis gi_setgroupent(int stayopen)
179*c6ec7d31SBrooks Davis {
180*c6ec7d31SBrooks Davis 
181*c6ec7d31SBrooks Davis 	if (!grstart())
182*c6ec7d31SBrooks Davis 		return 0;
183*c6ec7d31SBrooks Davis 	_gr_stayopen = stayopen;
184*c6ec7d31SBrooks Davis 	return 1;
185*c6ec7d31SBrooks Davis }
186*c6ec7d31SBrooks Davis 
187*c6ec7d31SBrooks Davis static void
188*c6ec7d31SBrooks Davis gi_endgrent(void)
189*c6ec7d31SBrooks Davis {
190*c6ec7d31SBrooks Davis 
191*c6ec7d31SBrooks Davis 	_gr_filesdone = 0;
192*c6ec7d31SBrooks Davis 	if (_gr_fp) {
193*c6ec7d31SBrooks Davis 		(void)fclose(_gr_fp);
194*c6ec7d31SBrooks Davis 		_gr_fp = NULL;
195*c6ec7d31SBrooks Davis 	}
196*c6ec7d31SBrooks Davis }
197*c6ec7d31SBrooks Davis 
198*c6ec7d31SBrooks Davis static int
199*c6ec7d31SBrooks Davis grstart(void)
200*c6ec7d31SBrooks Davis {
201*c6ec7d31SBrooks Davis 
202*c6ec7d31SBrooks Davis 	_gr_filesdone = 0;
203*c6ec7d31SBrooks Davis 	if (_gr_fp) {
204*c6ec7d31SBrooks Davis 		rewind(_gr_fp);
205*c6ec7d31SBrooks Davis 		return 1;
206*c6ec7d31SBrooks Davis 	}
207*c6ec7d31SBrooks Davis 	if (grfile[0] == '\0')			/* sanity check */
208*c6ec7d31SBrooks Davis 		return 0;
209*c6ec7d31SBrooks Davis 	return (_gr_fp = fopen(grfile, "r")) ? 1 : 0;
210*c6ec7d31SBrooks Davis }
211*c6ec7d31SBrooks Davis 
212*c6ec7d31SBrooks Davis 
213*c6ec7d31SBrooks Davis static int
214*c6ec7d31SBrooks Davis grscan(int search, gid_t gid, const char *name)
215*c6ec7d31SBrooks Davis {
216*c6ec7d31SBrooks Davis 
217*c6ec7d31SBrooks Davis 	if (_gr_filesdone)
218*c6ec7d31SBrooks Davis 		return 0;
219*c6ec7d31SBrooks Davis 	for (;;) {
220*c6ec7d31SBrooks Davis 		if (!fgets(grline, sizeof(grline), _gr_fp)) {
221*c6ec7d31SBrooks Davis 			if (!search)
222*c6ec7d31SBrooks Davis 				_gr_filesdone = 1;
223*c6ec7d31SBrooks Davis 			return 0;
224*c6ec7d31SBrooks Davis 		}
225*c6ec7d31SBrooks Davis 		/* skip lines that are too big */
226*c6ec7d31SBrooks Davis 		if (!strchr(grline, '\n')) {
227*c6ec7d31SBrooks Davis 			int ch;
228*c6ec7d31SBrooks Davis 
229*c6ec7d31SBrooks Davis 			while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
230*c6ec7d31SBrooks Davis 				;
231*c6ec7d31SBrooks Davis 			continue;
232*c6ec7d31SBrooks Davis 		}
233*c6ec7d31SBrooks Davis 		if (grmatchline(search, gid, name))
234*c6ec7d31SBrooks Davis 			return 1;
235*c6ec7d31SBrooks Davis 	}
236*c6ec7d31SBrooks Davis 	/* NOTREACHED */
237*c6ec7d31SBrooks Davis }
238*c6ec7d31SBrooks Davis 
239*c6ec7d31SBrooks Davis static int
240*c6ec7d31SBrooks Davis grmatchline(int search, gid_t gid, const char *name)
241*c6ec7d31SBrooks Davis {
242*c6ec7d31SBrooks Davis 	unsigned long	id;
243*c6ec7d31SBrooks Davis 	char		**m;
244*c6ec7d31SBrooks Davis 	char		*cp, *bp, *ep;
245*c6ec7d31SBrooks Davis 
246*c6ec7d31SBrooks Davis 	/* name may be NULL if search is nonzero */
247*c6ec7d31SBrooks Davis 
248*c6ec7d31SBrooks Davis 	bp = grline;
249*c6ec7d31SBrooks Davis 	memset(&_gr_group, 0, sizeof(_gr_group));
250*c6ec7d31SBrooks Davis 	_gr_group.gr_name = strsep(&bp, ":\n");
251*c6ec7d31SBrooks Davis 	if (search && name && strcmp(_gr_group.gr_name, name))
252*c6ec7d31SBrooks Davis 		return 0;
253*c6ec7d31SBrooks Davis 	_gr_group.gr_passwd = strsep(&bp, ":\n");
254*c6ec7d31SBrooks Davis 	if (!(cp = strsep(&bp, ":\n")))
255*c6ec7d31SBrooks Davis 		return 0;
256*c6ec7d31SBrooks Davis 	id = strtoul(cp, &ep, 10);
257*c6ec7d31SBrooks Davis 	if (id > GID_MAX || *ep != '\0')
258*c6ec7d31SBrooks Davis 		return 0;
259*c6ec7d31SBrooks Davis 	_gr_group.gr_gid = (gid_t)id;
260*c6ec7d31SBrooks Davis 	if (search && name == NULL && _gr_group.gr_gid != gid)
261*c6ec7d31SBrooks Davis 		return 0;
262*c6ec7d31SBrooks Davis 	cp = NULL;
263*c6ec7d31SBrooks Davis 	if (bp == NULL)
264*c6ec7d31SBrooks Davis 		return 0;
265*c6ec7d31SBrooks Davis 	for (_gr_group.gr_mem = m = members;; bp++) {
266*c6ec7d31SBrooks Davis 		if (m == &members[MAXGRP - 1])
267*c6ec7d31SBrooks Davis 			break;
268*c6ec7d31SBrooks Davis 		if (*bp == ',') {
269*c6ec7d31SBrooks Davis 			if (cp) {
270*c6ec7d31SBrooks Davis 				*bp = '\0';
271*c6ec7d31SBrooks Davis 				*m++ = cp;
272*c6ec7d31SBrooks Davis 				cp = NULL;
273*c6ec7d31SBrooks Davis 			}
274*c6ec7d31SBrooks Davis 		} else if (*bp == '\0' || *bp == '\n' || *bp == ' ') {
275*c6ec7d31SBrooks Davis 			if (cp) {
276*c6ec7d31SBrooks Davis 				*bp = '\0';
277*c6ec7d31SBrooks Davis 				*m++ = cp;
278*c6ec7d31SBrooks Davis 			}
279*c6ec7d31SBrooks Davis 			break;
280*c6ec7d31SBrooks Davis 		} else if (cp == NULL)
281*c6ec7d31SBrooks Davis 			cp = bp;
282*c6ec7d31SBrooks Davis 	}
283*c6ec7d31SBrooks Davis 	*m = NULL;
284*c6ec7d31SBrooks Davis 	return 1;
285*c6ec7d31SBrooks Davis }
286*c6ec7d31SBrooks Davis 
287*c6ec7d31SBrooks Davis 
288*c6ec7d31SBrooks Davis /*
289*c6ec7d31SBrooks Davis  * user lookup functions
290*c6ec7d31SBrooks Davis  */
291*c6ec7d31SBrooks Davis 
292*c6ec7d31SBrooks Davis static struct passwd *
293*c6ec7d31SBrooks Davis gi_getpwnam(const char *name)
294*c6ec7d31SBrooks Davis {
295*c6ec7d31SBrooks Davis 	int rval;
296*c6ec7d31SBrooks Davis 
297*c6ec7d31SBrooks Davis 	if (!pwstart())
298*c6ec7d31SBrooks Davis 		return NULL;
299*c6ec7d31SBrooks Davis 	rval = pwscan(1, 0, name);
300*c6ec7d31SBrooks Davis 	if (!_pw_stayopen)
301*c6ec7d31SBrooks Davis 		endpwent();
302*c6ec7d31SBrooks Davis 	return (rval) ? &_pw_passwd : NULL;
303*c6ec7d31SBrooks Davis }
304*c6ec7d31SBrooks Davis 
305*c6ec7d31SBrooks Davis static struct passwd *
306*c6ec7d31SBrooks Davis gi_getpwuid(uid_t uid)
307*c6ec7d31SBrooks Davis {
308*c6ec7d31SBrooks Davis 	int rval;
309*c6ec7d31SBrooks Davis 
310*c6ec7d31SBrooks Davis 	if (!pwstart())
311*c6ec7d31SBrooks Davis 		return NULL;
312*c6ec7d31SBrooks Davis 	rval = pwscan(1, uid, NULL);
313*c6ec7d31SBrooks Davis 	if (!_pw_stayopen)
314*c6ec7d31SBrooks Davis 		endpwent();
315*c6ec7d31SBrooks Davis 	return (rval) ? &_pw_passwd : NULL;
316*c6ec7d31SBrooks Davis }
317*c6ec7d31SBrooks Davis 
318*c6ec7d31SBrooks Davis static int
319*c6ec7d31SBrooks Davis gi_setpassent(int stayopen)
320*c6ec7d31SBrooks Davis {
321*c6ec7d31SBrooks Davis 
322*c6ec7d31SBrooks Davis 	if (!pwstart())
323*c6ec7d31SBrooks Davis 		return 0;
324*c6ec7d31SBrooks Davis 	_pw_stayopen = stayopen;
325*c6ec7d31SBrooks Davis 	return 1;
326*c6ec7d31SBrooks Davis }
327*c6ec7d31SBrooks Davis 
328*c6ec7d31SBrooks Davis static void
329*c6ec7d31SBrooks Davis gi_endpwent(void)
330*c6ec7d31SBrooks Davis {
331*c6ec7d31SBrooks Davis 
332*c6ec7d31SBrooks Davis 	_pw_filesdone = 0;
333*c6ec7d31SBrooks Davis 	if (_pw_fp) {
334*c6ec7d31SBrooks Davis 		(void)fclose(_pw_fp);
335*c6ec7d31SBrooks Davis 		_pw_fp = NULL;
336*c6ec7d31SBrooks Davis 	}
337*c6ec7d31SBrooks Davis }
338*c6ec7d31SBrooks Davis 
339*c6ec7d31SBrooks Davis static int
340*c6ec7d31SBrooks Davis pwstart(void)
341*c6ec7d31SBrooks Davis {
342*c6ec7d31SBrooks Davis 
343*c6ec7d31SBrooks Davis 	_pw_filesdone = 0;
344*c6ec7d31SBrooks Davis 	if (_pw_fp) {
345*c6ec7d31SBrooks Davis 		rewind(_pw_fp);
346*c6ec7d31SBrooks Davis 		return 1;
347*c6ec7d31SBrooks Davis 	}
348*c6ec7d31SBrooks Davis 	if (pwfile[0] == '\0')			/* sanity check */
349*c6ec7d31SBrooks Davis 		return 0;
350*c6ec7d31SBrooks Davis 	return (_pw_fp = fopen(pwfile, "r")) ? 1 : 0;
351*c6ec7d31SBrooks Davis }
352*c6ec7d31SBrooks Davis 
353*c6ec7d31SBrooks Davis 
354*c6ec7d31SBrooks Davis static int
355*c6ec7d31SBrooks Davis pwscan(int search, uid_t uid, const char *name)
356*c6ec7d31SBrooks Davis {
357*c6ec7d31SBrooks Davis 
358*c6ec7d31SBrooks Davis 	if (_pw_filesdone)
359*c6ec7d31SBrooks Davis 		return 0;
360*c6ec7d31SBrooks Davis 	for (;;) {
361*c6ec7d31SBrooks Davis 		if (!fgets(pwline, sizeof(pwline), _pw_fp)) {
362*c6ec7d31SBrooks Davis 			if (!search)
363*c6ec7d31SBrooks Davis 				_pw_filesdone = 1;
364*c6ec7d31SBrooks Davis 			return 0;
365*c6ec7d31SBrooks Davis 		}
366*c6ec7d31SBrooks Davis 		/* skip lines that are too big */
367*c6ec7d31SBrooks Davis 		if (!strchr(pwline, '\n')) {
368*c6ec7d31SBrooks Davis 			int ch;
369*c6ec7d31SBrooks Davis 
370*c6ec7d31SBrooks Davis 			while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
371*c6ec7d31SBrooks Davis 				;
372*c6ec7d31SBrooks Davis 			continue;
373*c6ec7d31SBrooks Davis 		}
374*c6ec7d31SBrooks Davis 		if (pwmatchline(search, uid, name))
375*c6ec7d31SBrooks Davis 			return 1;
376*c6ec7d31SBrooks Davis 	}
377*c6ec7d31SBrooks Davis 	/* NOTREACHED */
378*c6ec7d31SBrooks Davis }
379*c6ec7d31SBrooks Davis 
380*c6ec7d31SBrooks Davis static int
381*c6ec7d31SBrooks Davis pwmatchline(int search, uid_t uid, const char *name)
382*c6ec7d31SBrooks Davis {
383*c6ec7d31SBrooks Davis 	unsigned long	id;
384*c6ec7d31SBrooks Davis 	char		*cp, *bp, *ep;
385*c6ec7d31SBrooks Davis 
386*c6ec7d31SBrooks Davis 	/* name may be NULL if search is nonzero */
387*c6ec7d31SBrooks Davis 
388*c6ec7d31SBrooks Davis 	bp = pwline;
389*c6ec7d31SBrooks Davis 	memset(&_pw_passwd, 0, sizeof(_pw_passwd));
390*c6ec7d31SBrooks Davis 	_pw_passwd.pw_name = strsep(&bp, ":\n");		/* name */
391*c6ec7d31SBrooks Davis 	if (search && name && strcmp(_pw_passwd.pw_name, name))
392*c6ec7d31SBrooks Davis 		return 0;
393*c6ec7d31SBrooks Davis 
394*c6ec7d31SBrooks Davis 	_pw_passwd.pw_passwd = strsep(&bp, ":\n");		/* passwd */
395*c6ec7d31SBrooks Davis 
396*c6ec7d31SBrooks Davis 	if (!(cp = strsep(&bp, ":\n")))				/* uid */
397*c6ec7d31SBrooks Davis 		return 0;
398*c6ec7d31SBrooks Davis 	id = strtoul(cp, &ep, 10);
399*c6ec7d31SBrooks Davis 	if (id > UID_MAX || *ep != '\0')
400*c6ec7d31SBrooks Davis 		return 0;
401*c6ec7d31SBrooks Davis 	_pw_passwd.pw_uid = (uid_t)id;
402*c6ec7d31SBrooks Davis 	if (search && name == NULL && _pw_passwd.pw_uid != uid)
403*c6ec7d31SBrooks Davis 		return 0;
404*c6ec7d31SBrooks Davis 
405*c6ec7d31SBrooks Davis 	if (!(cp = strsep(&bp, ":\n")))				/* gid */
406*c6ec7d31SBrooks Davis 		return 0;
407*c6ec7d31SBrooks Davis 	id = strtoul(cp, &ep, 10);
408*c6ec7d31SBrooks Davis 	if (id > GID_MAX || *ep != '\0')
409*c6ec7d31SBrooks Davis 		return 0;
410*c6ec7d31SBrooks Davis 	_pw_passwd.pw_gid = (gid_t)id;
411*c6ec7d31SBrooks Davis 
412*c6ec7d31SBrooks Davis 	if (!(ep = strsep(&bp, ":")))				/* class */
413*c6ec7d31SBrooks Davis 		return 0;
414*c6ec7d31SBrooks Davis 	if (!(ep = strsep(&bp, ":")))				/* change */
415*c6ec7d31SBrooks Davis 		return 0;
416*c6ec7d31SBrooks Davis 	if (!(ep = strsep(&bp, ":")))				/* expire */
417*c6ec7d31SBrooks Davis 		return 0;
418*c6ec7d31SBrooks Davis 
419*c6ec7d31SBrooks Davis 	if (!(_pw_passwd.pw_gecos = strsep(&bp, ":\n")))	/* gecos */
420*c6ec7d31SBrooks Davis 		return 0;
421*c6ec7d31SBrooks Davis 	if (!(_pw_passwd.pw_dir = strsep(&bp, ":\n")))		/* directory */
422*c6ec7d31SBrooks Davis 		return 0;
423*c6ec7d31SBrooks Davis 	if (!(_pw_passwd.pw_shell = strsep(&bp, ":\n")))	/* shell */
424*c6ec7d31SBrooks Davis 		return 0;
425*c6ec7d31SBrooks Davis 
426*c6ec7d31SBrooks Davis 	if (strchr(bp, ':') != NULL)
427*c6ec7d31SBrooks Davis 		return 0;
428*c6ec7d31SBrooks Davis 
429*c6ec7d31SBrooks Davis 	return 1;
430*c6ec7d31SBrooks Davis }
431*c6ec7d31SBrooks Davis 
432