Annotation of 43BSDReno/usr.sbin/mkpasswd/mkpasswd.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980, 1983 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted provided
                      6:  * that: (1) source distributions retain this entire copyright notice and
                      7:  * comment, and (2) distributions including binaries display the following
                      8:  * acknowledgement:  ``This product includes software developed by the
                      9:  * University of California, Berkeley and its contributors'' in the
                     10:  * documentation or other materials provided with the distribution and in
                     11:  * all advertising materials mentioning features or use of this software.
                     12:  * Neither the name of the University nor the names of its contributors may
                     13:  * be used to endorse or promote products derived from this software without
                     14:  * specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: char copyright[] =
                     22: "@(#) Copyright (c) 1980, 1983 Regents of the University of California.\n\
                     23:  All rights reserved.\n";
                     24: #endif /* not lint */
                     25: 
                     26: #ifndef lint
                     27: static char sccsid[] = "@(#)mkpasswd.c 5.6 (Berkeley) 6/1/90";
                     28: #endif /* not lint */
                     29: 
                     30: #include <sys/param.h>
                     31: #include <sys/file.h>
                     32: #include <ndbm.h>
                     33: #include <pwd.h>
                     34: #include <stdio.h>
                     35: 
                     36: static FILE *_pw_fp;
                     37: static struct passwd _pw_passwd;
                     38: static off_t offset;
                     39: 
                     40: #define        MAXLINELENGTH   1024
                     41: static char line[MAXLINELENGTH];
                     42: 
                     43: /*
                     44:  * Mkpasswd does two things -- use the ``arg'' file to create ``arg''.{pag,dir}
                     45:  * for ndbm, and, if the -p flag is on, create a password file in the original
                     46:  * format.  It doesn't use the getpwent(3) routines because it has to figure
                     47:  * out offsets for the encrypted passwords to put in the dbm files.  One other
                     48:  * problem is that, since the addition of shadow passwords, getpwent(3) has to
                     49:  * use the dbm databases rather than simply scanning the actual file.  This
                     50:  * required the addition of a flag field to the dbm database to distinguish
                     51:  * between a record keyed by name, and one keyed by uid.
                     52:  */
                     53: 
                     54: main(argc, argv)
                     55:        int argc;
                     56:        char **argv;
                     57: {
                     58:        extern int errno, optind;
                     59:        register char *flag, *p, *t;
                     60:        register int makeold;
                     61:        FILE *oldfp;
                     62:        DBM *dp;
                     63:        datum key, content;
                     64:        int ch;
                     65:        char buf[8192], nbuf[50], *strerror();
                     66: 
                     67:        makeold = 0;
                     68:        while ((ch = getopt(argc, argv, "pv")) != EOF)
                     69:                switch(ch) {
                     70:                case 'p':                       /* create ``password.orig'' */
                     71:                        makeold = 1;
                     72:                        /* FALLTHROUGH */
                     73:                case 'v':                       /* backward compatible */
                     74:                        break;
                     75:                case '?':
                     76:                default:
                     77:                        usage();
                     78:                }
                     79:        argc -= optind;
                     80:        argv += optind;
                     81: 
                     82:        if (argc != 1)
                     83:                usage();
                     84: 
                     85:        if (!(_pw_fp = fopen(*argv, "r"))) {
                     86:                (void)fprintf(stderr,
                     87:                    "mkpasswd: %s: can't open for reading.\n", *argv);
                     88:                exit(1);
                     89:        }
                     90: 
                     91:        rmall(*argv);
                     92:        (void)umask(0);
                     93: 
                     94:        /* open old password format file, dbm files */
                     95:        if (makeold) {
                     96:                int oldfd;
                     97: 
                     98:                (void)sprintf(buf, "%s.orig", *argv);
                     99:                if ((oldfd = open(buf, O_WRONLY|O_CREAT|O_EXCL, 0644)) < 0) {
                    100:                        (void)fprintf(stderr, "mkpasswd: %s: %s\n", buf,
                    101:                            strerror(errno));
                    102:                        exit(1);
                    103:                }
                    104:                if (!(oldfp = fdopen(oldfd, "w"))) {
                    105:                        (void)fprintf(stderr, "mkpasswd: %s: fdopen failed.\n",
                    106:                            buf);
                    107:                        exit(1);
                    108:                }
                    109:        }
                    110:        if (!(dp = dbm_open(*argv, O_WRONLY|O_CREAT|O_EXCL, 0644))) {
                    111:                (void)fprintf(stderr, "mkpasswd: %s: %s\n", *argv,
                    112:                    strerror(errno));
                    113:                exit(1);
                    114:        }
                    115: 
                    116:        content.dptr = buf;
                    117:        while (scanpw()) {
                    118:                /* create dbm entry */
                    119:                p = buf;
                    120: #define        COMPACT(e)      t = e; while (*p++ = *t++);
                    121:                COMPACT(_pw_passwd.pw_name);
                    122:                (void)sprintf(nbuf, "%ld", offset);
                    123:                COMPACT(nbuf);
                    124:                bcopy((char *)&_pw_passwd.pw_uid, p, sizeof(int));
                    125:                p += sizeof(int);
                    126:                bcopy((char *)&_pw_passwd.pw_gid, p, sizeof(int));
                    127:                p += sizeof(int);
                    128:                bcopy((char *)&_pw_passwd.pw_change, p, sizeof(time_t));
                    129:                p += sizeof(time_t);
                    130:                COMPACT(_pw_passwd.pw_class);
                    131:                COMPACT(_pw_passwd.pw_gecos);
                    132:                COMPACT(_pw_passwd.pw_dir);
                    133:                COMPACT(_pw_passwd.pw_shell);
                    134:                bcopy((char *)&_pw_passwd.pw_expire, p, sizeof(time_t));
                    135:                p += sizeof(time_t);
                    136:                flag = p;
                    137:                *p++ = _PW_KEYBYNAME;
                    138:                content.dsize = p - buf;
                    139: #ifdef debug
                    140:                (void)printf("store %s, uid %d\n", _pw_passwd.pw_name,
                    141:                    _pw_passwd.pw_uid);
                    142: #endif
                    143:                key.dptr = _pw_passwd.pw_name;
                    144:                key.dsize = strlen(_pw_passwd.pw_name);
                    145:                if (dbm_store(dp, key, content, DBM_INSERT) < 0)
                    146:                        goto bad;
                    147:                key.dptr = (char *)&_pw_passwd.pw_uid;
                    148:                key.dsize = sizeof(int);
                    149:                *flag = _PW_KEYBYUID;
                    150:                if (dbm_store(dp, key, content, DBM_INSERT) < 0)
                    151:                        goto bad;
                    152: 
                    153:                /* create original format password file entry */
                    154:                if (!makeold)
                    155:                        continue;
                    156:                fprintf(oldfp, "%s:*:%d:%d:%s:%s:%s\n", _pw_passwd.pw_name,
                    157:                    _pw_passwd.pw_uid, _pw_passwd.pw_gid, _pw_passwd.pw_gecos,
                    158:                    _pw_passwd.pw_dir, _pw_passwd.pw_shell);
                    159:        }
                    160:        dbm_close(dp);
                    161:        exit(0);
                    162: 
                    163: bad:   (void)fprintf(stderr, "mkpasswd: dbm_store failed.\n");
                    164:        rmall(*argv);
                    165:        exit(1);
                    166: }
                    167: 
                    168: rmall(fname)
                    169:        char *fname;
                    170: {
                    171:        register char *p;
                    172:        char buf[MAXPATHLEN], *strcpy();
                    173: 
                    174:        for (p = strcpy(buf, fname); *p; ++p);
                    175:        bcopy(".pag", p, 5);
                    176:        (void)unlink(buf);
                    177:        bcopy(".dir", p, 5);
                    178:        (void)unlink(buf);
                    179:        bcopy(".orig", p, 6);
                    180:        (void)unlink(buf);
                    181: }
                    182: 
                    183: usage()
                    184: {
                    185:        (void)fprintf(stderr, "usage: mkpasswd [-p] passwd_file\n");
                    186:        exit(1);
                    187: }
                    188: 
                    189: /* from libc/gen/getpwent.c */
                    190: 
                    191: static
                    192: scanpw()
                    193: {
                    194:        register char *cp;
                    195:        long atol(), ftell();
                    196:        char *bp;
                    197:        char *fgets(), *strsep(), *index();
                    198: 
                    199:        for (;;) {
                    200:                offset = ftell(_pw_fp);
                    201:                if (!(fgets(line, sizeof(line), _pw_fp)))
                    202:                        return(0);
                    203:                /* skip lines that are too big */
                    204:                if (!index(line, '\n')) {
                    205:                        int ch;
                    206: 
                    207:                        while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
                    208:                                ;
                    209:                        continue;
                    210:                }
                    211:                bp = line;
                    212:                _pw_passwd.pw_name = strsep(&bp, ":\n");
                    213:                _pw_passwd.pw_passwd = strsep(&bp, ":\n");
                    214:                offset += _pw_passwd.pw_passwd - line;
                    215:                if (!(cp = strsep(&bp, ":\n")))
                    216:                        continue;
                    217:                _pw_passwd.pw_uid = atoi(cp);
                    218:                if (!(cp = strsep(&bp, ":\n")))
                    219:                        continue;
                    220:                _pw_passwd.pw_gid = atoi(cp);
                    221:                _pw_passwd.pw_class = strsep(&bp, ":\n");
                    222:                if (!(cp = strsep(&bp, ":\n")))
                    223:                        continue;
                    224:                _pw_passwd.pw_change = atol(cp);
                    225:                if (!(cp = strsep(&bp, ":\n")))
                    226:                        continue;
                    227:                _pw_passwd.pw_expire = atol(cp);
                    228:                _pw_passwd.pw_gecos = strsep(&bp, ":\n");
                    229:                _pw_passwd.pw_dir = strsep(&bp, ":\n");
                    230:                _pw_passwd.pw_shell = strsep(&bp, ":\n");
                    231:                return(1);
                    232:        }
                    233:        /* NOTREACHED */
                    234: }

unix.superglobalmegacorp.com

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