|
|
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.