122095Smckusick /* 2*61111Sbostic * Copyright (c) 1988, 1993 3*61111Sbostic * 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*61111Sbostic static char sccsid[] = "@(#)getpwent.c 8.1 (Berkeley) 06/04/93"; 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 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; 13551127Sbostic _pw_db = dbopen(p, O_RDONLY, 0, DB_HASH, 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