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