113736Ssam #ifndef lint 2*15650Sralph static char sccsid[] = "@(#)vipw.c 4.5 (Berkeley) 12/02/83"; 313736Ssam #endif 413736Ssam 513736Ssam #include <sys/types.h> 613736Ssam #include <sys/stat.h> 713736Ssam #include <sys/file.h> 813736Ssam 913736Ssam #include <stdio.h> 1013736Ssam #include <errno.h> 1113736Ssam #include <signal.h> 1213736Ssam 1313736Ssam /* 1413736Ssam * Password file editor with locking. 1513736Ssam */ 16*15650Sralph char temp[] = "/etc/ptmp"; 17*15650Sralph char temp_pag[] = "/etc/ptmp.pag"; 18*15650Sralph char temp_dir[] = "/etc/ptmp.dir"; 19*15650Sralph char passwd[] = "/etc/passwd"; 20*15650Sralph char passwd_pag[] = "/etc/passwd.pag"; 21*15650Sralph char passwd_dir[] = "/etc/passwd.dir"; 2213736Ssam char buf[BUFSIZ]; 2313736Ssam char *getenv(); 2413736Ssam char *index(); 2513736Ssam extern int errno; 2613736Ssam 2713736Ssam main(argc, argv) 2813736Ssam char *argv[]; 2913736Ssam { 3013736Ssam int fd; 3113736Ssam FILE *ft, *fp; 3213736Ssam char *editor; 3313736Ssam 34*15650Sralph signal(SIGHUP, SIG_IGN); 3513736Ssam signal(SIGINT, SIG_IGN); 3613736Ssam signal(SIGQUIT, SIG_IGN); 37*15650Sralph signal(SIGTSTP, SIG_IGN); 3813736Ssam setbuf(stderr, NULL); 3914911Sralph umask(0); 4013736Ssam fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644); 4113736Ssam if (fd < 0) { 4213736Ssam if (errno == EEXIST) { 4313736Ssam fprintf(stderr, "vipw: password file busy\n"); 4413736Ssam exit(1); 4513736Ssam } 4613736Ssam fprintf(stderr, "vipw: "); perror(temp); 4713736Ssam exit(1); 4813736Ssam } 4913736Ssam ft = fdopen(fd, "w"); 5013736Ssam if (ft == NULL) { 5113736Ssam fprintf(stderr, "vipw: "); perror(temp); 5213736Ssam goto bad; 5313736Ssam } 5413736Ssam fp = fopen(passwd, "r"); 5513736Ssam if (fp == NULL) { 5613736Ssam fprintf(stderr, "vipw: "); perror(passwd); 5713736Ssam goto bad; 5813736Ssam } 5913736Ssam while (fgets(buf, sizeof (buf) - 1, fp) != NULL) 6013736Ssam fputs(buf, ft); 6113736Ssam fclose(ft); fclose(fp); 6213736Ssam editor = getenv("EDITOR"); 6313736Ssam if (editor == 0) 6413736Ssam editor = "vi"; 6513736Ssam sprintf(buf, "%s %s", editor, temp); 6613736Ssam if (system(buf) == 0) { 6713736Ssam struct stat sbuf; 6813736Ssam int ok; 6913736Ssam 7013736Ssam /* sanity checks */ 7113736Ssam if (stat(temp, &sbuf) < 0) { 7213736Ssam fprintf(stderr, 7313736Ssam "vipw: can't stat temp file, %s unchanged\n", 7413736Ssam passwd); 7513736Ssam goto bad; 7613736Ssam } 7713736Ssam if (sbuf.st_size == 0) { 7813736Ssam fprintf(stderr, "vipw: bad temp file, %s unchanged\n", 7913736Ssam passwd); 8013736Ssam goto bad; 8113736Ssam } 8213736Ssam ft = fopen(temp, "r"); 8313736Ssam if (ft == NULL) { 8413736Ssam fprintf(stderr, 8513736Ssam "vipw: can't reopen temp file, %s unchanged\n", 8613736Ssam passwd); 8713736Ssam goto bad; 8813736Ssam } 8913736Ssam ok = 0; 9013736Ssam while (fgets(buf, sizeof (buf) - 1, ft) != NULL) { 9113736Ssam register char *cp; 9213736Ssam 9313736Ssam cp = index(buf, '\n'); 9413736Ssam if (cp == 0) 9513736Ssam continue; 9613736Ssam *cp = '\0'; 9713736Ssam cp = index(buf, ':'); 9813736Ssam if (cp == 0) 9913736Ssam continue; 10013736Ssam *cp = '\0'; 10113736Ssam if (strcmp(buf, "root")) 10213736Ssam continue; 10313736Ssam /* password */ 10413736Ssam cp = index(cp + 1, ':'); 10513736Ssam if (cp == 0) 10613736Ssam break; 10713736Ssam /* uid */ 10813736Ssam if (atoi(cp + 1) != 0) 10913736Ssam break; 11013736Ssam cp = index(cp + 1, ':'); 11113736Ssam if (cp == 0) 11213736Ssam break; 11313736Ssam /* gid */ 11413736Ssam cp = index(cp + 1, ':'); 11513736Ssam if (cp == 0) 11613736Ssam break; 11713736Ssam /* gecos */ 11813736Ssam cp = index(cp + 1, ':'); 11913736Ssam if (cp == 0) 12013736Ssam break; 12113736Ssam /* login directory */ 12213736Ssam if (strncmp(++cp, "/:")) 12313736Ssam break; 12413736Ssam cp += 2; 12513736Ssam if (*cp && strcmp(cp, "/bin/sh") && 12613736Ssam strcmp(cp, "/bin/csh")) 12713736Ssam break; 12813736Ssam ok++; 12913736Ssam } 13013736Ssam fclose(ft); 13113736Ssam if (ok) { 13215633Sralph if (makedb(temp) < 0) 13315633Sralph fprintf(stderr, "vipw: mkpasswd failed\n"); 13415633Sralph else if (rename(temp_pag, passwd_pag) < 0) 13515633Sralph fprintf(stderr, "vipw: "), perror(temp_pag); 13615633Sralph else if (rename(temp_dir, passwd_dir) < 0) 13715633Sralph fprintf(stderr, "vipw: "), perror(temp_dir); 13815633Sralph else if (rename(temp, passwd) < 0) 13913736Ssam fprintf(stderr, "vipw: "), perror("rename"); 14015166Sralph else 14115166Sralph exit(0); 14213736Ssam } else 14313736Ssam fprintf(stderr, 14413736Ssam "vipw: you mangled the temp file, %s unchanged\n", 14513736Ssam passwd); 14613736Ssam } 14713736Ssam bad: 148*15650Sralph unlink(temp_pag); 149*15650Sralph unlink(temp_dir); 15013736Ssam unlink(temp); 15115166Sralph exit(1); 15213736Ssam } 15315633Sralph 15415633Sralph makedb(file) 15515633Sralph char *file; 15615633Sralph { 15715633Sralph int status, pid, w; 15815633Sralph 15915633Sralph if ((pid = vfork()) == 0) { 16015633Sralph execl("/etc/mkpasswd", "mkpasswd", file, 0); 16115633Sralph _exit(127); 16215633Sralph } 16315633Sralph while ((w = wait(&status)) != pid && w != -1) 16415633Sralph ; 16515633Sralph if (w == -1 || status != 0) 16615633Sralph status = -1; 16715633Sralph return(status); 16815633Sralph } 169