pty hanging bug
[unix-history] / usr / src / usr.sbin / vipw / vipw.c
CommitLineData
4c6b79b5 1#ifndef lint
6b52f313 2static char sccsid[] = "@(#)vipw.c 4.3 (Berkeley) %G%";
4c6b79b5
SL
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 */
16char *temp = "/etc/ptmp";
17char *passwd = "/etc/passwd";
18char buf[BUFSIZ];
19char *getenv();
20char *index();
21extern int errno;
22
23main(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);
b2018160 34 umask(0);
4c6b79b5
SL
35 fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644);
36 if (fd < 0) {
37 if (errno == EEXIST) {
38 fprintf(stderr, "vipw: password file busy\n");
39 exit(1);
40 }
41 fprintf(stderr, "vipw: "); perror(temp);
42 exit(1);
43 }
44 ft = fdopen(fd, "w");
45 if (ft == NULL) {
46 fprintf(stderr, "vipw: "); perror(temp);
47 goto bad;
48 }
49 fp = fopen(passwd, "r");
50 if (fp == NULL) {
51 fprintf(stderr, "vipw: "); perror(passwd);
52 goto bad;
53 }
54 while (fgets(buf, sizeof (buf) - 1, fp) != NULL)
55 fputs(buf, ft);
56 fclose(ft); fclose(fp);
57 editor = getenv("EDITOR");
58 if (editor == 0)
59 editor = "vi";
60 sprintf(buf, "%s %s", editor, temp);
61 if (system(buf) == 0) {
62 struct stat sbuf;
63 int ok;
64
65 /* sanity checks */
66 if (stat(temp, &sbuf) < 0) {
67 fprintf(stderr,
68 "vipw: can't stat temp file, %s unchanged\n",
69 passwd);
70 goto bad;
71 }
72 if (sbuf.st_size == 0) {
73 fprintf(stderr, "vipw: bad temp file, %s unchanged\n",
74 passwd);
75 goto bad;
76 }
77 ft = fopen(temp, "r");
78 if (ft == NULL) {
79 fprintf(stderr,
80 "vipw: can't reopen temp file, %s unchanged\n",
81 passwd);
82 goto bad;
83 }
84 ok = 0;
85 while (fgets(buf, sizeof (buf) - 1, ft) != NULL) {
86 register char *cp;
87
88 cp = index(buf, '\n');
89 if (cp == 0)
90 continue;
91 *cp = '\0';
92 cp = index(buf, ':');
93 if (cp == 0)
94 continue;
95 *cp = '\0';
96 if (strcmp(buf, "root"))
97 continue;
98 /* password */
99 cp = index(cp + 1, ':');
100 if (cp == 0)
101 break;
102 /* uid */
103 if (atoi(cp + 1) != 0)
104 break;
105 cp = index(cp + 1, ':');
106 if (cp == 0)
107 break;
108 /* gid */
109 cp = index(cp + 1, ':');
110 if (cp == 0)
111 break;
112 /* gecos */
113 cp = index(cp + 1, ':');
114 if (cp == 0)
115 break;
116 /* login directory */
117 if (strncmp(++cp, "/:"))
118 break;
119 cp += 2;
120 if (*cp && strcmp(cp, "/bin/sh") &&
121 strcmp(cp, "/bin/csh"))
122 break;
123 ok++;
124 }
125 fclose(ft);
126 if (ok) {
127 if (rename(temp, passwd) < 0)
128 fprintf(stderr, "vipw: "), perror("rename");
6b52f313
RC
129 else
130 exit(0);
4c6b79b5
SL
131 } else
132 fprintf(stderr,
133 "vipw: you mangled the temp file, %s unchanged\n",
134 passwd);
135 }
136bad:
137 unlink(temp);
6b52f313 138 exit(1);
4c6b79b5 139}