Annotation of 43BSDReno/lib/libc/gen/getpwent.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.