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