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