113736Ssam #ifndef lint 2*14911Sralph static char sccsid[] = "@(#)vipw.c 4.2 (Berkeley) 09/07/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 */ 1613736Ssam char *temp = "/etc/ptmp"; 1713736Ssam char *passwd = "/etc/passwd"; 1813736Ssam char buf[BUFSIZ]; 1913736Ssam char *getenv(); 2013736Ssam char *index(); 2113736Ssam extern int errno; 2213736Ssam 2313736Ssam main(argc, argv) 2413736Ssam char *argv[]; 2513736Ssam { 2613736Ssam int fd; 2713736Ssam FILE *ft, *fp; 2813736Ssam char *editor; 2913736Ssam 3013736Ssam signal(SIGINT, SIG_IGN); 3113736Ssam signal(SIGQUIT, SIG_IGN); 3213736Ssam signal(SIGHUP, SIG_IGN); 3313736Ssam setbuf(stderr, NULL); 34*14911Sralph umask(0); 3513736Ssam fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644); 3613736Ssam if (fd < 0) { 3713736Ssam if (errno == EEXIST) { 3813736Ssam fprintf(stderr, "vipw: password file busy\n"); 3913736Ssam exit(1); 4013736Ssam } 4113736Ssam fprintf(stderr, "vipw: "); perror(temp); 4213736Ssam exit(1); 4313736Ssam } 4413736Ssam ft = fdopen(fd, "w"); 4513736Ssam if (ft == NULL) { 4613736Ssam fprintf(stderr, "vipw: "); perror(temp); 4713736Ssam goto bad; 4813736Ssam } 4913736Ssam fp = fopen(passwd, "r"); 5013736Ssam if (fp == NULL) { 5113736Ssam fprintf(stderr, "vipw: "); perror(passwd); 5213736Ssam goto bad; 5313736Ssam } 5413736Ssam while (fgets(buf, sizeof (buf) - 1, fp) != NULL) 5513736Ssam fputs(buf, ft); 5613736Ssam fclose(ft); fclose(fp); 5713736Ssam editor = getenv("EDITOR"); 5813736Ssam if (editor == 0) 5913736Ssam editor = "vi"; 6013736Ssam sprintf(buf, "%s %s", editor, temp); 6113736Ssam if (system(buf) == 0) { 6213736Ssam struct stat sbuf; 6313736Ssam int ok; 6413736Ssam 6513736Ssam /* sanity checks */ 6613736Ssam if (stat(temp, &sbuf) < 0) { 6713736Ssam fprintf(stderr, 6813736Ssam "vipw: can't stat temp file, %s unchanged\n", 6913736Ssam passwd); 7013736Ssam goto bad; 7113736Ssam } 7213736Ssam if (sbuf.st_size == 0) { 7313736Ssam fprintf(stderr, "vipw: bad temp file, %s unchanged\n", 7413736Ssam passwd); 7513736Ssam goto bad; 7613736Ssam } 7713736Ssam ft = fopen(temp, "r"); 7813736Ssam if (ft == NULL) { 7913736Ssam fprintf(stderr, 8013736Ssam "vipw: can't reopen temp file, %s unchanged\n", 8113736Ssam passwd); 8213736Ssam goto bad; 8313736Ssam } 8413736Ssam ok = 0; 8513736Ssam while (fgets(buf, sizeof (buf) - 1, ft) != NULL) { 8613736Ssam register char *cp; 8713736Ssam 8813736Ssam cp = index(buf, '\n'); 8913736Ssam if (cp == 0) 9013736Ssam continue; 9113736Ssam *cp = '\0'; 9213736Ssam cp = index(buf, ':'); 9313736Ssam if (cp == 0) 9413736Ssam continue; 9513736Ssam *cp = '\0'; 9613736Ssam if (strcmp(buf, "root")) 9713736Ssam continue; 9813736Ssam /* password */ 9913736Ssam cp = index(cp + 1, ':'); 10013736Ssam if (cp == 0) 10113736Ssam break; 10213736Ssam /* uid */ 10313736Ssam if (atoi(cp + 1) != 0) 10413736Ssam break; 10513736Ssam cp = index(cp + 1, ':'); 10613736Ssam if (cp == 0) 10713736Ssam break; 10813736Ssam /* gid */ 10913736Ssam cp = index(cp + 1, ':'); 11013736Ssam if (cp == 0) 11113736Ssam break; 11213736Ssam /* gecos */ 11313736Ssam cp = index(cp + 1, ':'); 11413736Ssam if (cp == 0) 11513736Ssam break; 11613736Ssam /* login directory */ 11713736Ssam if (strncmp(++cp, "/:")) 11813736Ssam break; 11913736Ssam cp += 2; 12013736Ssam if (*cp && strcmp(cp, "/bin/sh") && 12113736Ssam strcmp(cp, "/bin/csh")) 12213736Ssam break; 12313736Ssam ok++; 12413736Ssam } 12513736Ssam fclose(ft); 12613736Ssam if (ok) { 12713736Ssam if (rename(temp, passwd) < 0) 12813736Ssam fprintf(stderr, "vipw: "), perror("rename"); 12913736Ssam } else 13013736Ssam fprintf(stderr, 13113736Ssam "vipw: you mangled the temp file, %s unchanged\n", 13213736Ssam passwd); 13313736Ssam } 13413736Ssam bad: 13513736Ssam unlink(temp); 13613736Ssam } 137