xref: /csrg-svn/lib/libc/gen/getpwent.c (revision 47401)
122095Smckusick /*
236215Sbostic  * Copyright (c) 1988 The Regents of the University of California.
336215Sbostic  * All rights reserved.
436215Sbostic  *
542624Sbostic  * %sccs.include.redist.c%
622095Smckusick  */
722095Smckusick 
826560Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*47401Sbostic static char sccsid[] = "@(#)getpwent.c	5.21 (Berkeley) 03/14/91";
1036215Sbostic #endif /* LIBC_SCCS and not lint */
1122095Smckusick 
1246376Sbostic #include <sys/param.h>
1346376Sbostic #include <fcntl.h>
1446949Sbostic #include <db.h>
15*47401Sbostic #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 
2446376Sbostic static struct passwd _pw_passwd;	/* password structure */
2546949Sbostic static DB *_pw_db;			/* password database */
2646376Sbostic static int _pw_keynum;			/* key counter */
2746376Sbostic static int _pw_stayopen;		/* keep fd's open */
2846615Sbostic static int __hashpw(), __initdb();
292019Swnj 
3036855Sbostic struct passwd *
3136855Sbostic getpwent()
3236855Sbostic {
3346949Sbostic 	DBT key;
3446376Sbostic 	char bf[sizeof(_pw_keynum) + 1];
3536855Sbostic 
3646376Sbostic 	if (!_pw_db && !__initdb())
3736855Sbostic 		return((struct passwd *)NULL);
3846376Sbostic 
3946376Sbostic 	++_pw_keynum;
4046376Sbostic 	bf[0] = _PW_KEYBYNUM;
4146376Sbostic 	bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum));
4246949Sbostic 	key.data = (u_char *)bf;
4346949Sbostic 	key.size = sizeof(_pw_keynum) + 1;
4446949Sbostic 	return(__hashpw(&key) ? &_pw_passwd : (struct passwd *)NULL);
4536855Sbostic }
4636855Sbostic 
4736855Sbostic struct passwd *
4846376Sbostic getpwnam(name)
4946615Sbostic 	const char *name;
5036855Sbostic {
5146949Sbostic 	DBT key;
5246376Sbostic 	int len, rval;
5346376Sbostic 	char bf[UT_NAMESIZE + 1];
5436855Sbostic 
5546376Sbostic 	if (!_pw_db && !__initdb())
5636855Sbostic 		return((struct passwd *)NULL);
5736855Sbostic 
5846376Sbostic 	bf[0] = _PW_KEYBYNAME;
5946376Sbostic 	len = strlen(name);
6046376Sbostic 	bcopy(name, bf + 1, MIN(len, UT_NAMESIZE));
6146949Sbostic 	key.data = (u_char *)bf;
6246949Sbostic 	key.size = len + 1;
6346949Sbostic 	rval = __hashpw(&key);
6446376Sbostic 
6546659Sbostic 	if (!_pw_stayopen) {
6646949Sbostic 		(void)(_pw_db->close)(_pw_db);
6746949Sbostic 		_pw_db = (DB *)NULL;
6846376Sbostic 	}
6936855Sbostic 	return(rval ? &_pw_passwd : (struct passwd *)NULL);
7036855Sbostic }
7136855Sbostic 
7236855Sbostic struct passwd *
7346615Sbostic #ifdef __STDC__
7446615Sbostic getpwuid(uid_t uid)
7546615Sbostic #else
7636855Sbostic getpwuid(uid)
7736855Sbostic 	int uid;
7846615Sbostic #endif
7936855Sbostic {
8046949Sbostic 	DBT key;
8146659Sbostic 	int keyuid, rval;
8246660Sbostic 	char bf[sizeof(keyuid) + 1];
8336855Sbostic 
8446376Sbostic 	if (!_pw_db && !__initdb())
8536855Sbostic 		return((struct passwd *)NULL);
8636855Sbostic 
8746376Sbostic 	bf[0] = _PW_KEYBYUID;
8846659Sbostic 	keyuid = uid;
8946659Sbostic 	bcopy(&keyuid, bf + 1, sizeof(keyuid));
9046949Sbostic 	key.data = (u_char *)bf;
9146949Sbostic 	key.size = sizeof(keyuid) + 1;
9246949Sbostic 	rval = __hashpw(&key);
9336855Sbostic 
9446659Sbostic 	if (!_pw_stayopen) {
9546949Sbostic 		(void)(_pw_db->close)(_pw_db);
9646949Sbostic 		_pw_db = (DB *)NULL;
9736855Sbostic 	}
9846376Sbostic 	return(rval ? &_pw_passwd : (struct passwd *)NULL);
9936855Sbostic }
10036855Sbostic 
10146615Sbostic int
10236855Sbostic setpassent(stayopen)
10336855Sbostic 	int stayopen;
10436855Sbostic {
10546376Sbostic 	_pw_keynum = 0;
10636855Sbostic 	_pw_stayopen = stayopen;
10736855Sbostic 	return(1);
10836855Sbostic }
10936855Sbostic 
11046615Sbostic int
11146376Sbostic setpwent()
11246376Sbostic {
11346376Sbostic 	_pw_keynum = 0;
11446376Sbostic 	_pw_stayopen = 0;
11546376Sbostic 	return(1);
11646376Sbostic }
11746376Sbostic 
11836855Sbostic void
11936855Sbostic endpwent()
12036855Sbostic {
12146376Sbostic 	_pw_keynum = 0;
12236855Sbostic 	if (_pw_db) {
12346949Sbostic 		(void)(_pw_db->close)(_pw_db);
12446949Sbostic 		_pw_db = (DB *)NULL;
12541572Sedward 	}
12636855Sbostic }
12736855Sbostic 
12836855Sbostic static
12946376Sbostic __initdb()
13036855Sbostic {
13146376Sbostic 	static int warned;
13246376Sbostic 	char *p;
13336215Sbostic 
13446659Sbostic 	p = (geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB;
13546949Sbostic 	_pw_db = hash_open(p, O_RDONLY, 0, NULL);
13646949Sbostic 	if (_pw_db)
13736855Sbostic 		return(1);
13847290Sbostic 	if (!warned)
13947290Sbostic 		syslog(LOG_ERR, "%s: %m", p);
14046376Sbostic 	return(0);
1412019Swnj }
1422019Swnj 
14336215Sbostic static
14446376Sbostic __hashpw(key)
14546949Sbostic 	DBT *key;
1462019Swnj {
14736855Sbostic 	register char *p, *t;
14846376Sbostic 	static u_int max;
14946376Sbostic 	static char *line;
15046949Sbostic 	DBT data;
15136215Sbostic 
15246949Sbostic 	if ((_pw_db->get)(_pw_db, key, &data, 0))
15336215Sbostic 		return(0);
15446949Sbostic 	p = (char *)data.data;
15546949Sbostic 	if (data.size > max && !(line = realloc(line, max += 1024)))
15636215Sbostic 		return(0);
15746376Sbostic 
15836855Sbostic 	t = line;
15936855Sbostic #define	EXPAND(e)	e = t; while (*t++ = *p++);
16036855Sbostic 	EXPAND(_pw_passwd.pw_name);
16136855Sbostic 	EXPAND(_pw_passwd.pw_passwd);
16236855Sbostic 	bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int));
16336855Sbostic 	p += sizeof(int);
16436855Sbostic 	bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int));
16536855Sbostic 	p += sizeof(int);
16636855Sbostic 	bcopy(p, (char *)&_pw_passwd.pw_change, sizeof(time_t));
16736855Sbostic 	p += sizeof(time_t);
16836855Sbostic 	EXPAND(_pw_passwd.pw_class);
16936855Sbostic 	EXPAND(_pw_passwd.pw_gecos);
17036855Sbostic 	EXPAND(_pw_passwd.pw_dir);
17136855Sbostic 	EXPAND(_pw_passwd.pw_shell);
17236855Sbostic 	bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t));
17336855Sbostic 	p += sizeof(time_t);
17436215Sbostic 	return(1);
1752019Swnj }
176