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