xref: /original-bsd/lib/libc/gen/getpwent.c (revision c3e32dec)
1 /*
2  * Copyright (c) 1988, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)getpwent.c	8.1 (Berkeley) 06/04/93";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include <sys/param.h>
13 #include <fcntl.h>
14 #include <db.h>
15 #include <syslog.h>
16 #include <pwd.h>
17 #include <utmp.h>
18 #include <errno.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <limits.h>
23 
24 static struct passwd _pw_passwd;	/* password structure */
25 static DB *_pw_db;			/* password database */
26 static int _pw_keynum;			/* key counter */
27 static int _pw_stayopen;		/* keep fd's open */
28 static int __hashpw(), __initdb();
29 
30 struct passwd *
31 getpwent()
32 {
33 	DBT key;
34 	char bf[sizeof(_pw_keynum) + 1];
35 
36 	if (!_pw_db && !__initdb())
37 		return((struct passwd *)NULL);
38 
39 	++_pw_keynum;
40 	bf[0] = _PW_KEYBYNUM;
41 	bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum));
42 	key.data = (u_char *)bf;
43 	key.size = sizeof(_pw_keynum) + 1;
44 	return(__hashpw(&key) ? &_pw_passwd : (struct passwd *)NULL);
45 }
46 
47 struct passwd *
48 getpwnam(name)
49 	const char *name;
50 {
51 	DBT key;
52 	int len, rval;
53 	char bf[UT_NAMESIZE + 1];
54 
55 	if (!_pw_db && !__initdb())
56 		return((struct passwd *)NULL);
57 
58 	bf[0] = _PW_KEYBYNAME;
59 	len = strlen(name);
60 	bcopy(name, bf + 1, MIN(len, UT_NAMESIZE));
61 	key.data = (u_char *)bf;
62 	key.size = len + 1;
63 	rval = __hashpw(&key);
64 
65 	if (!_pw_stayopen) {
66 		(void)(_pw_db->close)(_pw_db);
67 		_pw_db = (DB *)NULL;
68 	}
69 	return(rval ? &_pw_passwd : (struct passwd *)NULL);
70 }
71 
72 struct passwd *
73 #ifdef __STDC__
74 getpwuid(uid_t uid)
75 #else
76 getpwuid(uid)
77 	int uid;
78 #endif
79 {
80 	DBT key;
81 	int keyuid, rval;
82 	char bf[sizeof(keyuid) + 1];
83 
84 	if (!_pw_db && !__initdb())
85 		return((struct passwd *)NULL);
86 
87 	bf[0] = _PW_KEYBYUID;
88 	keyuid = uid;
89 	bcopy(&keyuid, bf + 1, sizeof(keyuid));
90 	key.data = (u_char *)bf;
91 	key.size = sizeof(keyuid) + 1;
92 	rval = __hashpw(&key);
93 
94 	if (!_pw_stayopen) {
95 		(void)(_pw_db->close)(_pw_db);
96 		_pw_db = (DB *)NULL;
97 	}
98 	return(rval ? &_pw_passwd : (struct passwd *)NULL);
99 }
100 
101 int
102 setpassent(stayopen)
103 	int stayopen;
104 {
105 	_pw_keynum = 0;
106 	_pw_stayopen = stayopen;
107 	return(1);
108 }
109 
110 int
111 setpwent()
112 {
113 	_pw_keynum = 0;
114 	_pw_stayopen = 0;
115 	return(1);
116 }
117 
118 void
119 endpwent()
120 {
121 	_pw_keynum = 0;
122 	if (_pw_db) {
123 		(void)(_pw_db->close)(_pw_db);
124 		_pw_db = (DB *)NULL;
125 	}
126 }
127 
128 static
129 __initdb()
130 {
131 	static int warned;
132 	char *p;
133 
134 	p = (geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB;
135 	_pw_db = dbopen(p, O_RDONLY, 0, DB_HASH, NULL);
136 	if (_pw_db)
137 		return(1);
138 	if (!warned)
139 		syslog(LOG_ERR, "%s: %m", p);
140 	return(0);
141 }
142 
143 static
144 __hashpw(key)
145 	DBT *key;
146 {
147 	register char *p, *t;
148 	static u_int max;
149 	static char *line;
150 	DBT data;
151 
152 	if ((_pw_db->get)(_pw_db, key, &data, 0))
153 		return(0);
154 	p = (char *)data.data;
155 	if (data.size > max && !(line = realloc(line, max += 1024)))
156 		return(0);
157 
158 	t = line;
159 #define	EXPAND(e)	e = t; while (*t++ = *p++);
160 	EXPAND(_pw_passwd.pw_name);
161 	EXPAND(_pw_passwd.pw_passwd);
162 	bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int));
163 	p += sizeof(int);
164 	bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int));
165 	p += sizeof(int);
166 	bcopy(p, (char *)&_pw_passwd.pw_change, sizeof(time_t));
167 	p += sizeof(time_t);
168 	EXPAND(_pw_passwd.pw_class);
169 	EXPAND(_pw_passwd.pw_gecos);
170 	EXPAND(_pw_passwd.pw_dir);
171 	EXPAND(_pw_passwd.pw_shell);
172 	bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t));
173 	p += sizeof(time_t);
174 	return(1);
175 }
176