|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.