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