386 peculiar files touchup
[unix-history] / usr / src / lib / libc / gen / getpwent.c
CommitLineData
b8f253e8 1/*
196b72db
KB
2 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
269a7923 5 * %sccs.include.redist.c%
b8f253e8
KM
6 */
7
2ce81398 8#if defined(LIBC_SCCS) && !defined(lint)
269a7923 9static char sccsid[] = "@(#)getpwent.c 5.14 (Berkeley) %G%";
196b72db 10#endif /* LIBC_SCCS and not lint */
b8f253e8 11
196b72db
KB
12#include <sys/types.h>
13#include <sys/file.h>
a4b07b23
BJ
14#include <stdio.h>
15#include <pwd.h>
499a4b51 16#include <ndbm.h>
a4b07b23 17
196b72db
KB
18static DBM *_pw_db;
19static FILE *_pw_fp;
20static struct passwd _pw_passwd;
f63a642f 21static int _pw_getfirstkey, _pw_stayopen;
94aa68ce 22static char _pw_flag, *_pw_file = _PATH_PASSWD, _pw_master;
cc8dd839 23
352c409f 24#define MAXLINELENGTH 1024
196b72db 25static char line[MAXLINELENGTH];
a4b07b23 26
96efcec2
KB
27struct passwd *
28getpwent()
29{
96efcec2 30
94aa68ce 31 if (!_pw_fp && !start_pw(1))
96efcec2 32 return((struct passwd *)NULL);
94aa68ce
EW
33 if (!scanpw())
34 return((struct passwd *)NULL);
35 getpw();
36 return(&_pw_passwd);
96efcec2
KB
37}
38
39struct passwd *
40getpwnam(nam)
41 char *nam;
42{
43 int rval;
44
94aa68ce 45 if (!start_pw(0))
96efcec2
KB
46 return((struct passwd *)NULL);
47 if (_pw_db) {
48 datum key;
49
50 key.dptr = nam;
51 key.dsize = strlen(nam);
52 rval = fetch_pw(key);
53 } else /* _pw_fp */
cc84a39f 54 for (rval = 0; scanpw();)
96efcec2
KB
55 if (!strcmp(nam, _pw_passwd.pw_name)) {
56 rval = 1;
57 break;
58 }
59 if (!_pw_stayopen)
60 endpwent();
cc84a39f
KB
61 if (rval)
62 getpw();
96efcec2
KB
63 return(rval ? &_pw_passwd : (struct passwd *)NULL);
64}
65
66struct passwd *
67getpwuid(uid)
68 int uid;
69{
70 int rval;
71
94aa68ce 72 if (!start_pw(0))
96efcec2
KB
73 return((struct passwd *)NULL);
74 if (_pw_db) {
75 datum key;
76
77 key.dptr = (char *)&uid;
78 key.dsize = sizeof(uid);
79 rval = fetch_pw(key);
80 } else /* _pw_fp */
cc84a39f 81 for (rval = 0; scanpw();)
96efcec2
KB
82 if (_pw_passwd.pw_uid == uid) {
83 rval = 1;
84 break;
85 }
86 if (!_pw_stayopen)
87 endpwent();
cc84a39f
KB
88 if (rval)
89 getpw();
96efcec2
KB
90 return(rval ? &_pw_passwd : (struct passwd *)NULL);
91}
92
196b72db 93static
94aa68ce
EW
94start_pw(want_fp)
95 char want_fp; /* open _pw_fp also */
96efcec2 96{
33306bfc
KB
97 char *p;
98
96efcec2 99 if (_pw_db) {
f63a642f 100 _pw_getfirstkey = 1;
94aa68ce
EW
101 if (!want_fp)
102 return(1);
96efcec2
KB
103 }
104 if (_pw_fp) {
105 rewind(_pw_fp);
106 return(1);
107 }
94aa68ce 108 if (!_pw_db && (_pw_db = dbm_open(_pw_file, O_RDONLY, 0))) {
f63a642f 109 _pw_getfirstkey = 1;
94aa68ce
EW
110 if (!want_fp)
111 return(1);
f63a642f 112 }
33306bfc
KB
113 /*
114 * special case; if it's the official password file, look in
115 * the master password file, otherwise, look in the file itself.
116 */
117 p = strcmp(_pw_file, _PATH_PASSWD) ? _pw_file : _PATH_MASTERPASSWD;
94aa68ce
EW
118 if (_pw_fp = fopen(p, "r")) {
119 _pw_master = 1;
120 return(1);
121 }
122 /*
123 * If we really want to set up _pw_fp, then try again
124 * with the old file.
125 */
126 if (want_fp && p != _pw_file && (_pw_fp = fopen(_pw_file, "r"))) {
127 _pw_master = 0;
96efcec2 128 return(1);
94aa68ce 129 }
96efcec2
KB
130 return(0);
131}
132
133setpwent()
134{
135 return(setpassent(0));
136}
137
138setpassent(stayopen)
139 int stayopen;
140{
94aa68ce 141 if (!start_pw(0))
96efcec2
KB
142 return(0);
143 _pw_stayopen = stayopen;
144 return(1);
145}
146
147void
148endpwent()
149{
150 if (_pw_db) {
151 dbm_close(_pw_db);
152 _pw_db = (DBM *)NULL;
94aa68ce
EW
153 }
154 if (_pw_fp) {
96efcec2
KB
155 (void)fclose(_pw_fp);
156 _pw_fp = (FILE *)NULL;
157 }
96efcec2
KB
158}
159
160void
161setpwfile(file)
162 char *file;
163{
164 _pw_file = file;
96efcec2
KB
165}
166
167static
168scanpw()
a4b07b23 169{
196b72db 170 register char *cp;
96efcec2 171 long atol();
0f38f0b7 172 char *bp;
352c409f 173 char *fgets(), *strsep(), *index();
196b72db
KB
174
175 for (;;) {
96efcec2 176 if (!(fgets(line, sizeof(line), _pw_fp)))
196b72db 177 return(0);
0f38f0b7 178 bp = line;
352c409f 179 /* skip lines that are too big */
96efcec2 180 if (!index(line, '\n')) {
352c409f
KB
181 int ch;
182
183 while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
184 ;
185 continue;
186 }
0f38f0b7
MT
187 _pw_passwd.pw_name = strsep(&bp, ":\n");
188 _pw_passwd.pw_passwd = strsep(&bp, ":\n");
189 if (!(cp = strsep(&bp, ":\n")))
196b72db
KB
190 continue;
191 _pw_passwd.pw_uid = atoi(cp);
0f38f0b7 192 if (!(cp = strsep(&bp, ":\n")))
196b72db
KB
193 continue;
194 _pw_passwd.pw_gid = atoi(cp);
94aa68ce 195 if (_pw_master) {
0f38f0b7
MT
196 _pw_passwd.pw_class = strsep(&bp, ":\n");
197 if (!(cp = strsep(&bp, ":\n")))
94aa68ce
EW
198 continue;
199 _pw_passwd.pw_change = atol(cp);
0f38f0b7 200 if (!(cp = strsep(&bp, ":\n")))
94aa68ce
EW
201 continue;
202 _pw_passwd.pw_expire = atol(cp);
203 }
0f38f0b7
MT
204 _pw_passwd.pw_gecos = strsep(&bp, ":\n");
205 _pw_passwd.pw_dir = strsep(&bp, ":\n");
206 _pw_passwd.pw_shell = strsep(&bp, ":\n");
96efcec2
KB
207 if (!_pw_passwd.pw_shell)
208 continue;
209 return(1);
196b72db
KB
210 }
211 /* NOTREACHED */
a4b07b23
BJ
212}
213
196b72db 214static
96efcec2 215fetch_pw(key)
196b72db 216 datum key;
a4b07b23 217{
96efcec2 218 register char *p, *t;
196b72db 219
96efcec2
KB
220 /*
221 * the .dir file is LOCK_EX locked by programs that are
222 * renaming the various password files.
223 */
224 if (flock(dbm_dirfno(_pw_db), LOCK_SH))
196b72db 225 return(0);
96efcec2 226 if (!key.dptr)
f63a642f
KB
227 if (_pw_getfirstkey) {
228 _pw_getfirstkey = 0;
96efcec2
KB
229 key = dbm_firstkey(_pw_db);
230 } else
231 key = dbm_nextkey(_pw_db);
232 if (key.dptr)
233 key = dbm_fetch(_pw_db, key);
196b72db 234 (void)flock(dbm_dirfno(_pw_db), LOCK_UN);
96efcec2 235 if (!(p = key.dptr))
196b72db 236 return(0);
96efcec2
KB
237 t = line;
238#define EXPAND(e) e = t; while (*t++ = *p++);
239 EXPAND(_pw_passwd.pw_name);
240 EXPAND(_pw_passwd.pw_passwd);
241 bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int));
242 p += sizeof(int);
243 bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int));
244 p += sizeof(int);
245 bcopy(p, (char *)&_pw_passwd.pw_change, sizeof(time_t));
246 p += sizeof(time_t);
247 EXPAND(_pw_passwd.pw_class);
248 EXPAND(_pw_passwd.pw_gecos);
249 EXPAND(_pw_passwd.pw_dir);
250 EXPAND(_pw_passwd.pw_shell);
251 bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t));
252 p += sizeof(time_t);
253 _pw_flag = *p;
196b72db 254 return(1);
a4b07b23
BJ
255}
256
3b8a62fc
KB
257#define _MAX_PASSWD_SIZE 50
258static char pwbuf[_MAX_PASSWD_SIZE];
259
96efcec2
KB
260static
261getpw()
196b72db 262{
96efcec2 263 long pos, atol();
33306bfc 264 int fd, n;
96efcec2 265 char *p;
3b8a62fc 266 off_t lseek();
196b72db 267
972b418a
KB
268 if (geteuid())
269 return;
33306bfc
KB
270 /*
271 * special case; if it's the official password file, look in
272 * the master password file, otherwise, look in the file itself.
273 */
274 p = strcmp(_pw_file, _PATH_PASSWD) ? _pw_file : _PATH_MASTERPASSWD;
275 if ((fd = open(p, O_RDONLY, 0)) < 0)
276 return;
96efcec2 277 pos = atol(_pw_passwd.pw_passwd);
33306bfc 278 if (lseek(fd, pos, L_SET) != pos)
96efcec2 279 goto bad;
33306bfc 280 if ((n = read(fd, pwbuf, sizeof(pwbuf) - 1)) < 0)
96efcec2
KB
281 goto bad;
282 pwbuf[n] = '\0';
283 for (p = pwbuf; *p; ++p)
284 if (*p == ':') {
285 *p = '\0';
286 _pw_passwd.pw_passwd = pwbuf;
287 break;
288 }
33306bfc 289bad: (void)close(fd);
02d7fd83 290}