xref: /csrg-svn/lib/libc/gen/getpwent.c (revision 68953)
122095Smckusick /*
261111Sbostic  * Copyright (c) 1988, 1993
361111Sbostic  *	The Regents of the University of California.  All rights reserved.
436215Sbostic  *
542624Sbostic  * %sccs.include.redist.c%
622095Smckusick  */
722095Smckusick 
826560Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*68953Sbostic static char sccsid[] = "@(#)getpwent.c	8.2 (Berkeley) 04/27/95";
1036215Sbostic #endif /* LIBC_SCCS and not lint */
1122095Smckusick 
1246376Sbostic #include <sys/param.h>
1346376Sbostic #include <fcntl.h>
1446949Sbostic #include <db.h>
1547401Sbostic #include <syslog.h>
162019Swnj #include <pwd.h>
1746615Sbostic #include <utmp.h>
1846615Sbostic #include <errno.h>
1946376Sbostic #include <unistd.h>
2046615Sbostic #include <stdlib.h>
2146615Sbostic #include <string.h>
2246376Sbostic #include <limits.h>
232019Swnj 
24*68953Sbostic /*
25*68953Sbostic  * The lookup techniques and data extraction code here must be kept
26*68953Sbostic  * in sync with that in `pwd_mkdb'.
27*68953Sbostic  */
28*68953Sbostic 
2946376Sbostic static struct passwd _pw_passwd;	/* password structure */
3046949Sbostic static DB *_pw_db;			/* password database */
3146376Sbostic static int _pw_keynum;			/* key counter */
3246376Sbostic static int _pw_stayopen;		/* keep fd's open */
3346615Sbostic static int __hashpw(), __initdb();
342019Swnj 
3536855Sbostic struct passwd *
getpwent()3636855Sbostic getpwent()
3736855Sbostic {
3846949Sbostic 	DBT key;
3946376Sbostic 	char bf[sizeof(_pw_keynum) + 1];
4036855Sbostic 
4146376Sbostic 	if (!_pw_db && !__initdb())
4236855Sbostic 		return((struct passwd *)NULL);
4346376Sbostic 
4446376Sbostic 	++_pw_keynum;
4546376Sbostic 	bf[0] = _PW_KEYBYNUM;
4646376Sbostic 	bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum));
4746949Sbostic 	key.data = (u_char *)bf;
4846949Sbostic 	key.size = sizeof(_pw_keynum) + 1;
4946949Sbostic 	return(__hashpw(&key) ? &_pw_passwd : (struct passwd *)NULL);
5036855Sbostic }
5136855Sbostic 
5236855Sbostic struct passwd *
getpwnam(name)5346376Sbostic getpwnam(name)
5446615Sbostic 	const char *name;
5536855Sbostic {
5646949Sbostic 	DBT key;
5746376Sbostic 	int len, rval;
5846376Sbostic 	char bf[UT_NAMESIZE + 1];
5936855Sbostic 
6046376Sbostic 	if (!_pw_db && !__initdb())
6136855Sbostic 		return((struct passwd *)NULL);
6236855Sbostic 
6346376Sbostic 	bf[0] = _PW_KEYBYNAME;
6446376Sbostic 	len = strlen(name);
6546376Sbostic 	bcopy(name, bf + 1, MIN(len, UT_NAMESIZE));
6646949Sbostic 	key.data = (u_char *)bf;
6746949Sbostic 	key.size = len + 1;
6846949Sbostic 	rval = __hashpw(&key);
6946376Sbostic 
7046659Sbostic 	if (!_pw_stayopen) {
7146949Sbostic 		(void)(_pw_db->close)(_pw_db);
7246949Sbostic 		_pw_db = (DB *)NULL;
7346376Sbostic 	}
7436855Sbostic 	return(rval ? &_pw_passwd : (struct passwd *)NULL);
7536855Sbostic }
7636855Sbostic 
7736855Sbostic struct passwd *
getpwuid(uid)7836855Sbostic getpwuid(uid)
79*68953Sbostic 	uid_t uid;
8036855Sbostic {
8146949Sbostic 	DBT key;
8246659Sbostic 	int keyuid, rval;
8346660Sbostic 	char bf[sizeof(keyuid) + 1];
8436855Sbostic 
8546376Sbostic 	if (!_pw_db && !__initdb())
8636855Sbostic 		return((struct passwd *)NULL);
8736855Sbostic 
8846376Sbostic 	bf[0] = _PW_KEYBYUID;
8946659Sbostic 	keyuid = uid;
9046659Sbostic 	bcopy(&keyuid, bf + 1, sizeof(keyuid));
9146949Sbostic 	key.data = (u_char *)bf;
9246949Sbostic 	key.size = sizeof(keyuid) + 1;
9346949Sbostic 	rval = __hashpw(&key);
9436855Sbostic 
9546659Sbostic 	if (!_pw_stayopen) {
9646949Sbostic 		(void)(_pw_db->close)(_pw_db);
9746949Sbostic 		_pw_db = (DB *)NULL;
9836855Sbostic 	}
9946376Sbostic 	return(rval ? &_pw_passwd : (struct passwd *)NULL);
10036855Sbostic }
10136855Sbostic 
10246615Sbostic int
setpassent(stayopen)10336855Sbostic setpassent(stayopen)
10436855Sbostic 	int stayopen;
10536855Sbostic {
10646376Sbostic 	_pw_keynum = 0;
10736855Sbostic 	_pw_stayopen = stayopen;
10836855Sbostic 	return(1);
10936855Sbostic }
11036855Sbostic 
11146615Sbostic int
setpwent()11246376Sbostic setpwent()
11346376Sbostic {
11446376Sbostic 	_pw_keynum = 0;
11546376Sbostic 	_pw_stayopen = 0;
11646376Sbostic 	return(1);
11746376Sbostic }
11846376Sbostic 
11936855Sbostic void
endpwent()12036855Sbostic endpwent()
12136855Sbostic {
12246376Sbostic 	_pw_keynum = 0;
12336855Sbostic 	if (_pw_db) {
12446949Sbostic 		(void)(_pw_db->close)(_pw_db);
12546949Sbostic 		_pw_db = (DB *)NULL;
12641572Sedward 	}
12736855Sbostic }
12836855Sbostic 
12936855Sbostic static
__initdb()13046376Sbostic __initdb()
13136855Sbostic {
13246376Sbostic 	static int warned;
13346376Sbostic 	char *p;
13436215Sbostic 
13546659Sbostic 	p = (geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB;
13651127Sbostic 	_pw_db = dbopen(p, O_RDONLY, 0, DB_HASH, NULL);
13746949Sbostic 	if (_pw_db)
13836855Sbostic 		return(1);
13947290Sbostic 	if (!warned)
14047290Sbostic 		syslog(LOG_ERR, "%s: %m", p);
14146376Sbostic 	return(0);
1422019Swnj }
1432019Swnj 
14436215Sbostic static
__hashpw(key)14546376Sbostic __hashpw(key)
14646949Sbostic 	DBT *key;
1472019Swnj {
14836855Sbostic 	register char *p, *t;
14946376Sbostic 	static u_int max;
15046376Sbostic 	static char *line;
15146949Sbostic 	DBT data;
15236215Sbostic 
15346949Sbostic 	if ((_pw_db->get)(_pw_db, key, &data, 0))
15436215Sbostic 		return(0);
15546949Sbostic 	p = (char *)data.data;
15646949Sbostic 	if (data.size > max && !(line = realloc(line, max += 1024)))
15736215Sbostic 		return(0);
15846376Sbostic 
159*68953Sbostic 	/* THIS CODE MUST MATCH THAT IN pwd_mkdb. */
16036855Sbostic 	t = line;
16136855Sbostic #define	EXPAND(e)	e = t; while (*t++ = *p++);
162*68953Sbostic #define	SCALAR(v)	memmove(&(v), p, sizeof v); p += sizeof v
16336855Sbostic 	EXPAND(_pw_passwd.pw_name);
16436855Sbostic 	EXPAND(_pw_passwd.pw_passwd);
165*68953Sbostic 	SCALAR(_pw_passwd.pw_uid);
166*68953Sbostic 	SCALAR(_pw_passwd.pw_gid);
167*68953Sbostic 	SCALAR(_pw_passwd.pw_change);
16836855Sbostic 	EXPAND(_pw_passwd.pw_class);
16936855Sbostic 	EXPAND(_pw_passwd.pw_gecos);
17036855Sbostic 	EXPAND(_pw_passwd.pw_dir);
17136855Sbostic 	EXPAND(_pw_passwd.pw_shell);
172*68953Sbostic 	SCALAR(_pw_passwd.pw_expire);
17336215Sbostic 	return(1);
1742019Swnj }
175