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