1 #ifndef lint 2 static char sccsid[] = "@(#)vipw.c 4.1 (Berkeley) 07/03/83"; 3 #endif 4 5 #include <sys/types.h> 6 #include <sys/stat.h> 7 #include <sys/file.h> 8 9 #include <stdio.h> 10 #include <errno.h> 11 #include <signal.h> 12 13 /* 14 * Password file editor with locking. 15 */ 16 char *temp = "/etc/ptmp"; 17 char *passwd = "/etc/passwd"; 18 char buf[BUFSIZ]; 19 char *getenv(); 20 char *index(); 21 extern int errno; 22 23 main(argc, argv) 24 char *argv[]; 25 { 26 int fd; 27 FILE *ft, *fp; 28 char *editor; 29 30 signal(SIGINT, SIG_IGN); 31 signal(SIGQUIT, SIG_IGN); 32 signal(SIGHUP, SIG_IGN); 33 setbuf(stderr, NULL); 34 fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644); 35 if (fd < 0) { 36 if (errno == EEXIST) { 37 fprintf(stderr, "vipw: password file busy\n"); 38 exit(1); 39 } 40 fprintf(stderr, "vipw: "); perror(temp); 41 exit(1); 42 } 43 ft = fdopen(fd, "w"); 44 if (ft == NULL) { 45 fprintf(stderr, "vipw: "); perror(temp); 46 goto bad; 47 } 48 fp = fopen(passwd, "r"); 49 if (fp == NULL) { 50 fprintf(stderr, "vipw: "); perror(passwd); 51 goto bad; 52 } 53 while (fgets(buf, sizeof (buf) - 1, fp) != NULL) 54 fputs(buf, ft); 55 fclose(ft); fclose(fp); 56 editor = getenv("EDITOR"); 57 if (editor == 0) 58 editor = "vi"; 59 sprintf(buf, "%s %s", editor, temp); 60 if (system(buf) == 0) { 61 struct stat sbuf; 62 int ok; 63 64 /* sanity checks */ 65 if (stat(temp, &sbuf) < 0) { 66 fprintf(stderr, 67 "vipw: can't stat temp file, %s unchanged\n", 68 passwd); 69 goto bad; 70 } 71 if (sbuf.st_size == 0) { 72 fprintf(stderr, "vipw: bad temp file, %s unchanged\n", 73 passwd); 74 goto bad; 75 } 76 ft = fopen(temp, "r"); 77 if (ft == NULL) { 78 fprintf(stderr, 79 "vipw: can't reopen temp file, %s unchanged\n", 80 passwd); 81 goto bad; 82 } 83 ok = 0; 84 while (fgets(buf, sizeof (buf) - 1, ft) != NULL) { 85 register char *cp; 86 87 cp = index(buf, '\n'); 88 if (cp == 0) 89 continue; 90 *cp = '\0'; 91 cp = index(buf, ':'); 92 if (cp == 0) 93 continue; 94 *cp = '\0'; 95 if (strcmp(buf, "root")) 96 continue; 97 /* password */ 98 cp = index(cp + 1, ':'); 99 if (cp == 0) 100 break; 101 /* uid */ 102 if (atoi(cp + 1) != 0) 103 break; 104 cp = index(cp + 1, ':'); 105 if (cp == 0) 106 break; 107 /* gid */ 108 cp = index(cp + 1, ':'); 109 if (cp == 0) 110 break; 111 /* gecos */ 112 cp = index(cp + 1, ':'); 113 if (cp == 0) 114 break; 115 /* login directory */ 116 if (strncmp(++cp, "/:")) 117 break; 118 cp += 2; 119 if (*cp && strcmp(cp, "/bin/sh") && 120 strcmp(cp, "/bin/csh")) 121 break; 122 ok++; 123 } 124 fclose(ft); 125 if (ok) { 126 if (rename(temp, passwd) < 0) 127 fprintf(stderr, "vipw: "), perror("rename"); 128 } else 129 fprintf(stderr, 130 "vipw: you mangled the temp file, %s unchanged\n", 131 passwd); 132 } 133 bad: 134 unlink(temp); 135 } 136