xref: /csrg-svn/lib/libc/gen/getpwent.c (revision 46615)
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*46615Sbostic static char sccsid[] = "@(#)getpwent.c	5.16 (Berkeley) 02/24/91";
1036215Sbostic #endif /* LIBC_SCCS and not lint */
1122095Smckusick 
1246376Sbostic #include <sys/param.h>
1346376Sbostic #include <fcntl.h>
142019Swnj #include <pwd.h>
1516416Sralph #include <ndbm.h>
16*46615Sbostic #include <utmp.h>
17*46615Sbostic #include <errno.h>
1846376Sbostic #include <unistd.h>
19*46615Sbostic #include <stdlib.h>
20*46615Sbostic #include <string.h>
2146376Sbostic #include <limits.h>
222019Swnj 
2346376Sbostic static struct passwd _pw_passwd;	/* password structure */
2446376Sbostic static DBM *_pw_db;			/* password database */
2546376Sbostic static int _pw_keynum;			/* key counter */
2646376Sbostic static int _pw_stayopen;		/* keep fd's open */
2746376Sbostic static int _pw_euid;
28*46615Sbostic static int __hashpw(), __initdb();
292019Swnj 
3036855Sbostic struct passwd *
3136855Sbostic getpwent()
3236855Sbostic {
3346376Sbostic 	datum key;
3446376Sbostic 	int rval;
3546376Sbostic 	char bf[sizeof(_pw_keynum) + 1];
3636855Sbostic 
3746376Sbostic 	if (!_pw_db && !__initdb())
3836855Sbostic 		return((struct passwd *)NULL);
3946376Sbostic 
4046376Sbostic 	++_pw_keynum;
4146376Sbostic 	bf[0] = _PW_KEYBYNUM;
4246376Sbostic 	bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum));
4346376Sbostic 	key.dptr = bf;
4446376Sbostic 	key.dsize = sizeof(_pw_keynum) + 1;
4546376Sbostic 	rval = __hashpw(key);
4646376Sbostic 
4746376Sbostic 	/* Can't leave secure database open. */
4846376Sbostic 	if (!_pw_euid) {
4946376Sbostic 		(void)dbm_close(_pw_db);
5046376Sbostic 		_pw_db = (DBM *)NULL;
5146376Sbostic 	}
5246376Sbostic 	return(rval ? &_pw_passwd : (struct passwd *)NULL);
5336855Sbostic }
5436855Sbostic 
5536855Sbostic struct passwd *
5646376Sbostic getpwnam(name)
57*46615Sbostic 	const char *name;
5836855Sbostic {
5946376Sbostic 	datum key;
6046376Sbostic 	int len, rval;
6146376Sbostic 	char bf[UT_NAMESIZE + 1];
6236855Sbostic 
6346376Sbostic 	if (!_pw_db && !__initdb())
6436855Sbostic 		return((struct passwd *)NULL);
6536855Sbostic 
6646376Sbostic 	bf[0] = _PW_KEYBYNAME;
6746376Sbostic 	len = strlen(name);
6846376Sbostic 	bcopy(name, bf + 1, MIN(len, UT_NAMESIZE));
6946376Sbostic 	key.dptr = bf;
7046376Sbostic 	key.dsize = len + 1;
7146376Sbostic 	rval = __hashpw(key);
7246376Sbostic 
7346376Sbostic 	/* Can't leave secure database open. */
7446376Sbostic 	if (!_pw_stayopen || !_pw_euid) {
7546376Sbostic 		(void)dbm_close(_pw_db);
7646376Sbostic 		_pw_db = (DBM *)NULL;
7746376Sbostic 	}
7836855Sbostic 	return(rval ? &_pw_passwd : (struct passwd *)NULL);
7936855Sbostic }
8036855Sbostic 
8136855Sbostic struct passwd *
82*46615Sbostic #ifdef __STDC__
83*46615Sbostic getpwuid(uid_t uid)
84*46615Sbostic #else
8536855Sbostic getpwuid(uid)
8636855Sbostic 	int uid;
87*46615Sbostic #endif
8836855Sbostic {
8946376Sbostic 	datum key;
9036855Sbostic 	int rval;
9146376Sbostic 	char bf[sizeof(uid) + 1];
9236855Sbostic 
9346376Sbostic 	if (!_pw_db && !__initdb())
9436855Sbostic 		return((struct passwd *)NULL);
9536855Sbostic 
9646376Sbostic 	bf[0] = _PW_KEYBYUID;
9746376Sbostic 	bcopy(&uid, bf + 1, sizeof(uid));
9846376Sbostic 	key.dptr = bf;
9946376Sbostic 	key.dsize = sizeof(uid) + 1;
10046376Sbostic 	rval = __hashpw(key);
10136855Sbostic 
10246376Sbostic 	/* Can't leave secure database open. */
10346376Sbostic 	if (!_pw_stayopen || !_pw_euid) {
10446376Sbostic 		(void)dbm_close(_pw_db);
10546376Sbostic 		_pw_db = (DBM *)NULL;
10636855Sbostic 	}
10746376Sbostic 	return(rval ? &_pw_passwd : (struct passwd *)NULL);
10836855Sbostic }
10936855Sbostic 
110*46615Sbostic int
11136855Sbostic setpassent(stayopen)
11236855Sbostic 	int stayopen;
11336855Sbostic {
11446376Sbostic 	_pw_keynum = 0;
11536855Sbostic 	_pw_stayopen = stayopen;
11636855Sbostic 	return(1);
11736855Sbostic }
11836855Sbostic 
119*46615Sbostic int
12046376Sbostic setpwent()
12146376Sbostic {
12246376Sbostic 	_pw_keynum = 0;
12346376Sbostic 	_pw_stayopen = 0;
12446376Sbostic 	return(1);
12546376Sbostic }
12646376Sbostic 
12736855Sbostic void
12836855Sbostic endpwent()
12936855Sbostic {
13046376Sbostic 	_pw_keynum = 0;
13136855Sbostic 	if (_pw_db) {
13246376Sbostic 		(void)dbm_close(_pw_db);
13336855Sbostic 		_pw_db = (DBM *)NULL;
13441572Sedward 	}
13536855Sbostic }
13636855Sbostic 
13736855Sbostic static
13846376Sbostic __initdb()
13936855Sbostic {
14046376Sbostic 	static int warned;
14146376Sbostic 	char *p;
14236215Sbostic 
14346376Sbostic 	p = (_pw_euid = geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB;
14446376Sbostic 	if (_pw_db = dbm_open(p, O_RDONLY, 0))
14536855Sbostic 		return(1);
14646376Sbostic 	if (!warned) {
147*46615Sbostic 		(void)write(STDERR_FILENO, "getpwent: ", 10);
148*46615Sbostic 		(void)write(STDERR_FILENO, p, strlen(p));
149*46615Sbostic 		(void)write(STDERR_FILENO, ": ", 2);
150*46615Sbostic 		p = strerror(errno);
151*46615Sbostic 		(void)write(STDERR_FILENO, p, strlen(p));
152*46615Sbostic 		(void)write(STDERR_FILENO, "\n", 1);
15346376Sbostic 		warned = 1;
15436215Sbostic 	}
15546376Sbostic 	return(0);
1562019Swnj }
1572019Swnj 
15836215Sbostic static
15946376Sbostic __hashpw(key)
16036215Sbostic 	datum key;
1612019Swnj {
16236855Sbostic 	register char *p, *t;
16346376Sbostic 	static u_int max;
16446376Sbostic 	static char *line;
16546376Sbostic 	datum dp;
16636215Sbostic 
16746376Sbostic 	dp = dbm_fetch(_pw_db, key);
16846376Sbostic 	if (!(p = dp.dptr))
16936215Sbostic 		return(0);
17046376Sbostic 	if (dp.dsize > max && !(line = (char *)realloc(line, max += 1024)))
17136215Sbostic 		return(0);
17246376Sbostic 
17336855Sbostic 	t = line;
17436855Sbostic #define	EXPAND(e)	e = t; while (*t++ = *p++);
17536855Sbostic 	EXPAND(_pw_passwd.pw_name);
17636855Sbostic 	EXPAND(_pw_passwd.pw_passwd);
17736855Sbostic 	bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int));
17836855Sbostic 	p += sizeof(int);
17936855Sbostic 	bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int));
18036855Sbostic 	p += sizeof(int);
18136855Sbostic 	bcopy(p, (char *)&_pw_passwd.pw_change, sizeof(time_t));
18236855Sbostic 	p += sizeof(time_t);
18336855Sbostic 	EXPAND(_pw_passwd.pw_class);
18436855Sbostic 	EXPAND(_pw_passwd.pw_gecos);
18536855Sbostic 	EXPAND(_pw_passwd.pw_dir);
18636855Sbostic 	EXPAND(_pw_passwd.pw_shell);
18736855Sbostic 	bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t));
18836855Sbostic 	p += sizeof(time_t);
18936215Sbostic 	return(1);
1902019Swnj }
191