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