1*21186Sdist /* 2*21186Sdist * Copyright (c) 1980 Regents of the University of California. 3*21186Sdist * All rights reserved. The Berkeley software License Agreement 4*21186Sdist * specifies the terms and conditions for redistribution. 5*21186Sdist */ 6*21186Sdist 713736Ssam #ifndef lint 8*21186Sdist char copyright[] = 9*21186Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10*21186Sdist All rights reserved.\n"; 11*21186Sdist #endif not lint 1213736Ssam 13*21186Sdist #ifndef lint 14*21186Sdist static char sccsid[] = "@(#)vipw.c 5.1 (Berkeley) 05/28/85"; 15*21186Sdist #endif not lint 16*21186Sdist 1713736Ssam #include <sys/types.h> 1813736Ssam #include <sys/stat.h> 1913736Ssam #include <sys/file.h> 2013736Ssam 2113736Ssam #include <stdio.h> 2213736Ssam #include <errno.h> 2313736Ssam #include <signal.h> 2413736Ssam 2513736Ssam /* 2613736Ssam * Password file editor with locking. 2713736Ssam */ 2815650Sralph char temp[] = "/etc/ptmp"; 2915650Sralph char temp_pag[] = "/etc/ptmp.pag"; 3015650Sralph char temp_dir[] = "/etc/ptmp.dir"; 3115650Sralph char passwd[] = "/etc/passwd"; 3215650Sralph char passwd_pag[] = "/etc/passwd.pag"; 3315650Sralph char passwd_dir[] = "/etc/passwd.dir"; 3413736Ssam char buf[BUFSIZ]; 3513736Ssam char *getenv(); 3613736Ssam char *index(); 3713736Ssam extern int errno; 3813736Ssam 3913736Ssam main(argc, argv) 4013736Ssam char *argv[]; 4113736Ssam { 4213736Ssam int fd; 4313736Ssam FILE *ft, *fp; 4413736Ssam char *editor; 4513736Ssam 4615650Sralph signal(SIGHUP, SIG_IGN); 4713736Ssam signal(SIGINT, SIG_IGN); 4813736Ssam signal(SIGQUIT, SIG_IGN); 4913736Ssam setbuf(stderr, NULL); 5014911Sralph umask(0); 5113736Ssam fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644); 5213736Ssam if (fd < 0) { 5313736Ssam if (errno == EEXIST) { 5413736Ssam fprintf(stderr, "vipw: password file busy\n"); 5513736Ssam exit(1); 5613736Ssam } 5713736Ssam fprintf(stderr, "vipw: "); perror(temp); 5813736Ssam exit(1); 5913736Ssam } 6013736Ssam ft = fdopen(fd, "w"); 6113736Ssam if (ft == NULL) { 6213736Ssam fprintf(stderr, "vipw: "); perror(temp); 6313736Ssam goto bad; 6413736Ssam } 6513736Ssam fp = fopen(passwd, "r"); 6613736Ssam if (fp == NULL) { 6713736Ssam fprintf(stderr, "vipw: "); perror(passwd); 6813736Ssam goto bad; 6913736Ssam } 7013736Ssam while (fgets(buf, sizeof (buf) - 1, fp) != NULL) 7113736Ssam fputs(buf, ft); 7213736Ssam fclose(ft); fclose(fp); 7313736Ssam editor = getenv("EDITOR"); 7413736Ssam if (editor == 0) 7513736Ssam editor = "vi"; 7613736Ssam sprintf(buf, "%s %s", editor, temp); 7713736Ssam if (system(buf) == 0) { 7813736Ssam struct stat sbuf; 7913736Ssam int ok; 8013736Ssam 8113736Ssam /* sanity checks */ 8213736Ssam if (stat(temp, &sbuf) < 0) { 8313736Ssam fprintf(stderr, 8413736Ssam "vipw: can't stat temp file, %s unchanged\n", 8513736Ssam passwd); 8613736Ssam goto bad; 8713736Ssam } 8813736Ssam if (sbuf.st_size == 0) { 8913736Ssam fprintf(stderr, "vipw: bad temp file, %s unchanged\n", 9013736Ssam passwd); 9113736Ssam goto bad; 9213736Ssam } 9313736Ssam ft = fopen(temp, "r"); 9413736Ssam if (ft == NULL) { 9513736Ssam fprintf(stderr, 9613736Ssam "vipw: can't reopen temp file, %s unchanged\n", 9713736Ssam passwd); 9813736Ssam goto bad; 9913736Ssam } 10013736Ssam ok = 0; 10113736Ssam while (fgets(buf, sizeof (buf) - 1, ft) != NULL) { 10213736Ssam register char *cp; 10313736Ssam 10413736Ssam cp = index(buf, '\n'); 10513736Ssam if (cp == 0) 10613736Ssam continue; 10713736Ssam *cp = '\0'; 10813736Ssam cp = index(buf, ':'); 10913736Ssam if (cp == 0) 11013736Ssam continue; 11113736Ssam *cp = '\0'; 11213736Ssam if (strcmp(buf, "root")) 11313736Ssam continue; 11413736Ssam /* password */ 11513736Ssam cp = index(cp + 1, ':'); 11613736Ssam if (cp == 0) 11713736Ssam break; 11813736Ssam /* uid */ 11913736Ssam if (atoi(cp + 1) != 0) 12013736Ssam break; 12113736Ssam cp = index(cp + 1, ':'); 12213736Ssam if (cp == 0) 12313736Ssam break; 12413736Ssam /* gid */ 12513736Ssam cp = index(cp + 1, ':'); 12613736Ssam if (cp == 0) 12713736Ssam break; 12813736Ssam /* gecos */ 12913736Ssam cp = index(cp + 1, ':'); 13013736Ssam if (cp == 0) 13113736Ssam break; 13213736Ssam /* login directory */ 13318108Sbloom if (strncmp(++cp, "/:", 2)) 13413736Ssam break; 13513736Ssam cp += 2; 13613736Ssam if (*cp && strcmp(cp, "/bin/sh") && 13713736Ssam strcmp(cp, "/bin/csh")) 13813736Ssam break; 13913736Ssam ok++; 14013736Ssam } 14113736Ssam fclose(ft); 14213736Ssam if (ok) { 14315633Sralph if (makedb(temp) < 0) 14415633Sralph fprintf(stderr, "vipw: mkpasswd failed\n"); 14515633Sralph else if (rename(temp_pag, passwd_pag) < 0) 14615633Sralph fprintf(stderr, "vipw: "), perror(temp_pag); 14715633Sralph else if (rename(temp_dir, passwd_dir) < 0) 14815633Sralph fprintf(stderr, "vipw: "), perror(temp_dir); 14915633Sralph else if (rename(temp, passwd) < 0) 15013736Ssam fprintf(stderr, "vipw: "), perror("rename"); 15115166Sralph else 15215166Sralph exit(0); 15313736Ssam } else 15413736Ssam fprintf(stderr, 15513736Ssam "vipw: you mangled the temp file, %s unchanged\n", 15613736Ssam passwd); 15713736Ssam } 15813736Ssam bad: 15915650Sralph unlink(temp_pag); 16015650Sralph unlink(temp_dir); 16113736Ssam unlink(temp); 16215166Sralph exit(1); 16313736Ssam } 16415633Sralph 16515633Sralph makedb(file) 16615633Sralph char *file; 16715633Sralph { 16815633Sralph int status, pid, w; 16915633Sralph 17015633Sralph if ((pid = vfork()) == 0) { 17115633Sralph execl("/etc/mkpasswd", "mkpasswd", file, 0); 17215633Sralph _exit(127); 17315633Sralph } 17415633Sralph while ((w = wait(&status)) != pid && w != -1) 17515633Sralph ; 17615633Sralph if (w == -1 || status != 0) 17715633Sralph status = -1; 17815633Sralph return(status); 17915633Sralph } 180