Annotation of 43BSD/etc/vipw.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: char copyright[] =
                      9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
                     10:  All rights reserved.\n";
                     11: #endif not lint
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)vipw.c     5.1 (Berkeley) 5/28/85";
                     15: #endif not lint
                     16: 
                     17: #include <sys/types.h>
                     18: #include <sys/stat.h>
                     19: #include <sys/file.h>
                     20: 
                     21: #include <stdio.h>
                     22: #include <errno.h>
                     23: #include <signal.h>
                     24: 
                     25: /*
                     26:  * Password file editor with locking.
                     27:  */
                     28: char   temp[] = "/etc/ptmp";
                     29: char   temp_pag[] = "/etc/ptmp.pag";
                     30: char   temp_dir[] = "/etc/ptmp.dir";
                     31: char   passwd[] = "/etc/passwd";
                     32: char   passwd_pag[] = "/etc/passwd.pag";
                     33: char   passwd_dir[] = "/etc/passwd.dir";
                     34: char   buf[BUFSIZ];
                     35: char   *getenv();
                     36: char   *index();
                     37: extern int errno;
                     38: 
                     39: main(argc, argv)
                     40:        char *argv[];
                     41: {
                     42:        int fd;
                     43:        FILE *ft, *fp;
                     44:        char *editor;
                     45: 
                     46:        signal(SIGHUP, SIG_IGN);
                     47:        signal(SIGINT, SIG_IGN);
                     48:        signal(SIGQUIT, SIG_IGN);
                     49:        setbuf(stderr, NULL);
                     50:        umask(0);
                     51:        fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644);
                     52:        if (fd < 0) {
                     53:                if (errno == EEXIST) {
                     54:                        fprintf(stderr, "vipw: password file busy\n");
                     55:                        exit(1);
                     56:                }
                     57:                fprintf(stderr, "vipw: "); perror(temp);
                     58:                exit(1);
                     59:        }
                     60:        ft = fdopen(fd, "w");
                     61:        if (ft == NULL) {
                     62:                fprintf(stderr, "vipw: "); perror(temp);
                     63:                goto bad;
                     64:        }
                     65:        fp = fopen(passwd, "r");
                     66:        if (fp == NULL) {
                     67:                fprintf(stderr, "vipw: "); perror(passwd);
                     68:                goto bad;
                     69:        }
                     70:        while (fgets(buf, sizeof (buf) - 1, fp) != NULL)
                     71:                fputs(buf, ft);
                     72:        fclose(ft); fclose(fp);
                     73:        editor = getenv("EDITOR");
                     74:        if (editor == 0)
                     75:                editor = "vi";
                     76:        sprintf(buf, "%s %s", editor, temp);
                     77:        if (system(buf) == 0) {
                     78:                struct stat sbuf;
                     79:                int ok;
                     80: 
                     81:                /* sanity checks */
                     82:                if (stat(temp, &sbuf) < 0) {
                     83:                        fprintf(stderr,
                     84:                            "vipw: can't stat temp file, %s unchanged\n",
                     85:                            passwd);
                     86:                        goto bad;
                     87:                }
                     88:                if (sbuf.st_size == 0) {
                     89:                        fprintf(stderr, "vipw: bad temp file, %s unchanged\n",
                     90:                            passwd);
                     91:                        goto bad;
                     92:                }
                     93:                ft = fopen(temp, "r");
                     94:                if (ft == NULL) {
                     95:                        fprintf(stderr,
                     96:                            "vipw: can't reopen temp file, %s unchanged\n",
                     97:                            passwd);
                     98:                        goto bad;
                     99:                }
                    100:                ok = 0;
                    101:                while (fgets(buf, sizeof (buf) - 1, ft) != NULL) {
                    102:                        register char *cp;
                    103: 
                    104:                        cp = index(buf, '\n');
                    105:                        if (cp == 0)
                    106:                                continue;
                    107:                        *cp = '\0';
                    108:                        cp = index(buf, ':');
                    109:                        if (cp == 0)
                    110:                                continue;
                    111:                        *cp = '\0';
                    112:                        if (strcmp(buf, "root"))
                    113:                                continue;
                    114:                        /* password */
                    115:                        cp = index(cp + 1, ':');
                    116:                        if (cp == 0)
                    117:                                break;
                    118:                        /* uid */
                    119:                        if (atoi(cp + 1) != 0)
                    120:                                break;
                    121:                        cp = index(cp + 1, ':');
                    122:                        if (cp == 0)
                    123:                                break;
                    124:                        /* gid */
                    125:                        cp = index(cp + 1, ':');
                    126:                        if (cp == 0)
                    127:                                break;
                    128:                        /* gecos */
                    129:                        cp = index(cp + 1, ':');
                    130:                        if (cp == 0)
                    131:                                break;
                    132:                        /* login directory */
                    133:                        if (strncmp(++cp, "/:", 2))
                    134:                                break;
                    135:                        cp += 2;
                    136:                        if (*cp && strcmp(cp, "/bin/sh") &&
                    137:                            strcmp(cp, "/bin/csh"))
                    138:                                break;
                    139:                        ok++;
                    140:                }
                    141:                fclose(ft);
                    142:                if (ok) {
                    143:                        if (makedb(temp) < 0)
                    144:                                fprintf(stderr, "vipw: mkpasswd failed\n");
                    145:                        else if (rename(temp_pag, passwd_pag) < 0)
                    146:                                fprintf(stderr, "vipw: "), perror(temp_pag);
                    147:                        else if (rename(temp_dir, passwd_dir) < 0)
                    148:                                fprintf(stderr, "vipw: "), perror(temp_dir);
                    149:                        else if (rename(temp, passwd) < 0)
                    150:                                fprintf(stderr, "vipw: "), perror("rename");
                    151:                        else
                    152:                                exit(0);
                    153:                } else
                    154:                        fprintf(stderr,
                    155:                            "vipw: you mangled the temp file, %s unchanged\n",
                    156:                            passwd);
                    157:        }
                    158: bad:
                    159:        unlink(temp_pag);
                    160:        unlink(temp_dir);
                    161:        unlink(temp);
                    162:        exit(1);
                    163: }
                    164: 
                    165: makedb(file)
                    166:        char *file;
                    167: {
                    168:        int status, pid, w;
                    169: 
                    170:        if ((pid = vfork()) == 0) {
                    171:                execl("/etc/mkpasswd", "mkpasswd", file, 0);
                    172:                _exit(127);
                    173:        }
                    174:        while ((w = wait(&status)) != pid && w != -1)
                    175:                ;
                    176:        if (w == -1 || status != 0)
                    177:                status = -1;
                    178:        return(status);
                    179: }

unix.superglobalmegacorp.com

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