|
|
1.1 root 1: /*
2: * Copyright (c) 1988 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #if defined(LIBC_SCCS) && !defined(lint)
21: static char sccsid[] = "@(#)getpwent.c 5.14 (Berkeley) 6/1/90";
22: #endif /* LIBC_SCCS and not lint */
23:
24: #include <sys/types.h>
25: #include <sys/file.h>
26: #include <stdio.h>
27: #include <pwd.h>
28: #include <ndbm.h>
29:
30: static DBM *_pw_db;
31: static FILE *_pw_fp;
32: static struct passwd _pw_passwd;
33: static int _pw_getfirstkey, _pw_stayopen;
34: static char _pw_flag, *_pw_file = _PATH_PASSWD, _pw_master;
35:
36: #define MAXLINELENGTH 1024
37: static char line[MAXLINELENGTH];
38:
39: struct passwd *
40: getpwent()
41: {
42:
43: if (!_pw_fp && !start_pw(1))
44: return((struct passwd *)NULL);
45: if (!scanpw())
46: return((struct passwd *)NULL);
47: getpw();
48: return(&_pw_passwd);
49: }
50:
51: struct passwd *
52: getpwnam(nam)
53: char *nam;
54: {
55: int rval;
56:
57: if (!start_pw(0))
58: return((struct passwd *)NULL);
59: if (_pw_db) {
60: datum key;
61:
62: key.dptr = nam;
63: key.dsize = strlen(nam);
64: rval = fetch_pw(key);
65: } else /* _pw_fp */
66: for (rval = 0; scanpw();)
67: if (!strcmp(nam, _pw_passwd.pw_name)) {
68: rval = 1;
69: break;
70: }
71: if (!_pw_stayopen)
72: endpwent();
73: if (rval)
74: getpw();
75: return(rval ? &_pw_passwd : (struct passwd *)NULL);
76: }
77:
78: struct passwd *
79: getpwuid(uid)
80: int uid;
81: {
82: int rval;
83:
84: if (!start_pw(0))
85: return((struct passwd *)NULL);
86: if (_pw_db) {
87: datum key;
88:
89: key.dptr = (char *)&uid;
90: key.dsize = sizeof(uid);
91: rval = fetch_pw(key);
92: } else /* _pw_fp */
93: for (rval = 0; scanpw();)
94: if (_pw_passwd.pw_uid == uid) {
95: rval = 1;
96: break;
97: }
98: if (!_pw_stayopen)
99: endpwent();
100: if (rval)
101: getpw();
102: return(rval ? &_pw_passwd : (struct passwd *)NULL);
103: }
104:
105: static
106: start_pw(want_fp)
107: char want_fp; /* open _pw_fp also */
108: {
109: char *p;
110:
111: if (_pw_db) {
112: _pw_getfirstkey = 1;
113: if (!want_fp)
114: return(1);
115: }
116: if (_pw_fp) {
117: rewind(_pw_fp);
118: return(1);
119: }
120: if (!_pw_db && (_pw_db = dbm_open(_pw_file, O_RDONLY, 0))) {
121: _pw_getfirstkey = 1;
122: if (!want_fp)
123: return(1);
124: }
125: /*
126: * special case; if it's the official password file, look in
127: * the master password file, otherwise, look in the file itself.
128: */
129: p = strcmp(_pw_file, _PATH_PASSWD) ? _pw_file : _PATH_MASTERPASSWD;
130: if (_pw_fp = fopen(p, "r")) {
131: _pw_master = 1;
132: return(1);
133: }
134: /*
135: * If we really want to set up _pw_fp, then try again
136: * with the old file.
137: */
138: if (want_fp && p != _pw_file && (_pw_fp = fopen(_pw_file, "r"))) {
139: _pw_master = 0;
140: return(1);
141: }
142: return(0);
143: }
144:
145: setpwent()
146: {
147: return(setpassent(0));
148: }
149:
150: setpassent(stayopen)
151: int stayopen;
152: {
153: if (!start_pw(0))
154: return(0);
155: _pw_stayopen = stayopen;
156: return(1);
157: }
158:
159: void
160: endpwent()
161: {
162: if (_pw_db) {
163: dbm_close(_pw_db);
164: _pw_db = (DBM *)NULL;
165: }
166: if (_pw_fp) {
167: (void)fclose(_pw_fp);
168: _pw_fp = (FILE *)NULL;
169: }
170: }
171:
172: void
173: setpwfile(file)
174: char *file;
175: {
176: _pw_file = file;
177: }
178:
179: static
180: scanpw()
181: {
182: register char *cp;
183: long atol();
184: char *bp;
185: char *fgets(), *strsep(), *index();
186:
187: for (;;) {
188: if (!(fgets(line, sizeof(line), _pw_fp)))
189: return(0);
190: bp = line;
191: /* skip lines that are too big */
192: if (!index(line, '\n')) {
193: int ch;
194:
195: while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
196: ;
197: continue;
198: }
199: _pw_passwd.pw_name = strsep(&bp, ":\n");
200: _pw_passwd.pw_passwd = strsep(&bp, ":\n");
201: if (!(cp = strsep(&bp, ":\n")))
202: continue;
203: _pw_passwd.pw_uid = atoi(cp);
204: if (!(cp = strsep(&bp, ":\n")))
205: continue;
206: _pw_passwd.pw_gid = atoi(cp);
207: if (_pw_master) {
208: _pw_passwd.pw_class = strsep(&bp, ":\n");
209: if (!(cp = strsep(&bp, ":\n")))
210: continue;
211: _pw_passwd.pw_change = atol(cp);
212: if (!(cp = strsep(&bp, ":\n")))
213: continue;
214: _pw_passwd.pw_expire = atol(cp);
215: }
216: _pw_passwd.pw_gecos = strsep(&bp, ":\n");
217: _pw_passwd.pw_dir = strsep(&bp, ":\n");
218: _pw_passwd.pw_shell = strsep(&bp, ":\n");
219: if (!_pw_passwd.pw_shell)
220: continue;
221: return(1);
222: }
223: /* NOTREACHED */
224: }
225:
226: static
227: fetch_pw(key)
228: datum key;
229: {
230: register char *p, *t;
231:
232: /*
233: * the .dir file is LOCK_EX locked by programs that are
234: * renaming the various password files.
235: */
236: if (flock(dbm_dirfno(_pw_db), LOCK_SH))
237: return(0);
238: if (!key.dptr)
239: if (_pw_getfirstkey) {
240: _pw_getfirstkey = 0;
241: key = dbm_firstkey(_pw_db);
242: } else
243: key = dbm_nextkey(_pw_db);
244: if (key.dptr)
245: key = dbm_fetch(_pw_db, key);
246: (void)flock(dbm_dirfno(_pw_db), LOCK_UN);
247: if (!(p = key.dptr))
248: return(0);
249: t = line;
250: #define EXPAND(e) e = t; while (*t++ = *p++);
251: EXPAND(_pw_passwd.pw_name);
252: EXPAND(_pw_passwd.pw_passwd);
253: bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int));
254: p += sizeof(int);
255: bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int));
256: p += sizeof(int);
257: bcopy(p, (char *)&_pw_passwd.pw_change, sizeof(time_t));
258: p += sizeof(time_t);
259: EXPAND(_pw_passwd.pw_class);
260: EXPAND(_pw_passwd.pw_gecos);
261: EXPAND(_pw_passwd.pw_dir);
262: EXPAND(_pw_passwd.pw_shell);
263: bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t));
264: p += sizeof(time_t);
265: _pw_flag = *p;
266: return(1);
267: }
268:
269: #define _MAX_PASSWD_SIZE 50
270: static char pwbuf[_MAX_PASSWD_SIZE];
271:
272: static
273: getpw()
274: {
275: long pos, atol();
276: int fd, n;
277: char *p;
278: off_t lseek();
279:
280: if (geteuid())
281: return;
282: /*
283: * special case; if it's the official password file, look in
284: * the master password file, otherwise, look in the file itself.
285: */
286: p = strcmp(_pw_file, _PATH_PASSWD) ? _pw_file : _PATH_MASTERPASSWD;
287: if ((fd = open(p, O_RDONLY, 0)) < 0)
288: return;
289: pos = atol(_pw_passwd.pw_passwd);
290: if (lseek(fd, pos, L_SET) != pos)
291: goto bad;
292: if ((n = read(fd, pwbuf, sizeof(pwbuf) - 1)) < 0)
293: goto bad;
294: pwbuf[n] = '\0';
295: for (p = pwbuf; *p; ++p)
296: if (*p == ':') {
297: *p = '\0';
298: _pw_passwd.pw_passwd = pwbuf;
299: break;
300: }
301: bad: (void)close(fd);
302: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.