1 /* $NetBSD: getpwent.c,v 1.10 2008/11/28 19:39:00 sborrill Exp $ */
4 * Copyright (c) 1987, 1988, 1989, 1993, 1994, 1995
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * Copied from: lib/libc/gen/getpwent.c
34 * NetBSD: getpwent.c,v 1.48 2000/10/03 03:22:26 enami Exp
35 * and then gutted, leaving only /etc/master.passwd support.
38 #include <sys/cdefs.h>
41 #define endpwent _endpwent
42 #define getpwent _getpwent
43 #define getpwent_r _getpwent_r
44 #define getpwuid _getpwuid
45 #define getpwnam _getpwnam
46 #define setpwent _setpwent
47 #define setpassent _setpassent
48 #define getpwuid_r _getpwuid_r
49 #define getpwnam_r _getpwnam_r
51 __weak_alias(endpwent
,_endpwent
)
52 __weak_alias(getpwent
,_getpwent
)
53 __weak_alias(getpwent_r
,_getpwent_r
)
54 __weak_alias(getpwuid
,_getpwuid
)
55 __weak_alias(getpwnam
,_getpwnam
)
56 __weak_alias(setpwent
,_setpwent
)
57 __weak_alias(setpassent
,_setpassent
)
58 __weak_alias(getpwuid_r
,_getpwuid_r
)
59 __weak_alias(getpwnam_r
,_getpwnam_r
)
61 __weak_alias(__getpwent50
,_getpwent
)
62 __weak_alias(__getpwent_r50
,_getpwent_r
)
63 __weak_alias(__getpwuid50
,_getpwuid
)
64 __weak_alias(__getpwnam50
,_getpwnam
)
65 __weak_alias(__getpwuid_r50
,_getpwuid_r
)
66 __weak_alias(__getpwnam_r50
,_getpwnam_r
)
69 #include <sys/param.h>
77 static int pwstart(void);
78 static int pwscan(int, uid_t
, const char *, struct passwd
*,
80 static int pwmatchline(int, uid_t
, const char *, struct passwd
*,
84 static struct passwd _pw_passwd
; /* password structure */
85 static int _pw_stayopen
; /* keep fd's open */
86 static int _pw_filesdone
;
88 #define MAXLINELENGTH 1024
90 static char pwline
[MAXLINELENGTH
];
96 if ((!_pw_fp
&& !pwstart()) ||
97 !pwscan(0, 0, NULL
, &_pw_passwd
, pwline
, sizeof(pwline
)))
103 getpwent_r(struct passwd
*pwres
, char *buf
, size_t bufsiz
,
108 if (!_pw_fp
&& !pwstart())
110 rval
= !pwscan(0, 0, NULL
, pwres
, buf
, bufsiz
);
119 getpwnam(const char *name
)
122 return getpwnam_r(name
, &_pw_passwd
, pwline
, sizeof(pwline
),
123 &pwd
) == 0 ? pwd
: NULL
;
127 getpwnam_r(const char *name
, struct passwd
*pwres
, char *buf
, size_t bufsiz
,
134 rval
= !pwscan(1, 0, name
, pwres
, buf
, bufsiz
);
148 return getpwuid_r(uid
, &_pw_passwd
, pwline
, sizeof(pwline
),
149 &pwd
) == 0 ? pwd
: NULL
;
153 getpwuid_r(uid_t uid
, struct passwd
*pwres
, char *buf
, size_t bufsiz
,
160 rval
= !pwscan(1, uid
, NULL
, pwres
, buf
, bufsiz
);
174 (void) setpassent(0);
178 setpassent(int stayopen
)
183 _pw_stayopen
= stayopen
;
193 (void)fclose(_pw_fp
);
207 return (_pw_fp
= fopen(_PATH_MASTERPASSWD
, "r")) ? 1 : 0;
212 pwscan(int search
, uid_t uid
, const char *name
, struct passwd
*pwd
, char *buf
,
219 if (!fgets(buf
, bufsiz
, _pw_fp
)) {
224 /* skip lines that are too big */
225 if (!strchr(buf
, '\n')) {
228 while ((ch
= getc(_pw_fp
)) != '\n' && ch
!= EOF
)
232 if (pwmatchline(search
, uid
, name
, pwd
, buf
))
239 pwmatchline(int search
, uid_t uid
, const char *name
, struct passwd
*pwd
,
245 /* name may be NULL if search is nonzero */
248 memset(pwd
, 0, sizeof(*pwd
));
249 pwd
->pw_name
= strsep(&bp
, ":\n"); /* name */
250 if (search
&& name
&& strcmp(pwd
->pw_name
, name
))
253 pwd
->pw_passwd
= strsep(&bp
, ":\n"); /* passwd */
255 if (!(cp
= strsep(&bp
, ":\n"))) /* uid */
257 id
= strtoul(cp
, &ep
, 10);
258 if (id
> UID_MAX
|| *ep
!= '\0')
260 pwd
->pw_uid
= (uid_t
)id
;
261 if (search
&& name
== NULL
&& pwd
->pw_uid
!= uid
)
264 if (!(cp
= strsep(&bp
, ":\n"))) /* gid */
266 id
= strtoul(cp
, &ep
, 10);
267 if (id
> GID_MAX
|| *ep
!= '\0')
269 pwd
->pw_gid
= (gid_t
)id
;
271 if (!(pwd
->pw_class
= strsep(&bp
, ":"))) /* class */
273 if (!(ep
= strsep(&bp
, ":"))) /* change */
275 if (!(ep
= strsep(&bp
, ":"))) /* expire */
278 if (!(pwd
->pw_gecos
= strsep(&bp
, ":\n"))) /* gecos */
280 if (!(pwd
->pw_dir
= strsep(&bp
, ":\n"))) /* directory */
282 if (!(pwd
->pw_shell
= strsep(&bp
, ":\n"))) /* shell */
285 if (strchr(bp
, ':') != NULL
)